summaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
authornetop://ウィビ <paul@webb.page>2026-04-11 15:01:41 -0700
committernetop://ウィビ <paul@webb.page>2026-04-11 15:01:41 -0700
commit3f7f5dc1b5ca4ba6a9acaf101d2e52b64edd2705 (patch)
tree9c496baae8c825b548fbec43f198006856ee30c6 /README.md
initial commitHEADprimary
Diffstat (limited to 'README.md')
-rw-r--r--README.md404
1 files changed, 404 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b5f8615
--- /dev/null
+++ b/README.md
@@ -0,0 +1,404 @@
+
+![](banner.png "ChronVer banner")
+
+**[ChronVer](https://chronver.org) (Chronological Versioning) is calendar‑based versioning.** In the age of rapid software releases, knowing _when_ something released is more important than arbitrary numbers from an outdated versioning system that most people never adhere to anyway. Finally, versioning for the rest of us.
+
+
+
+## Why ChronVer?
+
+```
+2025.07.21 ← You know exactly when this was released
+v3.2.1 ← You have no idea when this happened
+```
+
+Semantic versioning is great for large systems like libraries and computers. Most software would benefit from **time‑based versioning** that's immediately understandable to everyone on a team, not just the technical‑minded.
+
+
+
+## Format
+
+```
+YYYY.MM.DD[.CHANGESET][-FEATURE|-break]
+```
+
+### Examples
+
+| Version | Description |
+|------------------------|-------------------------------|
+| `2025.07.21` | Released July 21st, 2025 |
+| `2025.07.21.1` | First hotfix that day |
+| `2025.07.21.3` | Third change that day |
+| `2025.07.21-feature` | Feature branch for that date |
+| `2025.07.21.1-feature` | Feature branch with changeset |
+| `2025.07.21.1-break` | Breaking change |
+
+
+
+## Installation
+
+### Deno
+
+```sh
+# install
+deno add jsr:@chronver/chronver
+
+# import in your code
+import { ChronVer } from "jsr:@chronver/chronver";
+
+# install CLI globally
+# "resolver diagnostics" will appear when using this method but it's fine
+deno install --allow-read --allow-write --global --name chronver https://raw.githubusercontent.com/ChronVer/chronver/refs/heads/primary/cli.ts --import-map https://raw.githubusercontent.com/ChronVer/chronver/refs/heads/primary/deno.json
+```
+
+### npm/bun
+
+```sh
+# install via npm
+npx jsr add @chronver/chronver
+
+# install via bun
+bunx jsr add @chronver/chronver
+
+# import in your code
+import { ChronVer } from "@chronver/chronver";
+```
+
+ChronVer is especially powerful with [husky](https://typicode.github.io/husky/). Here's how I use it in my Node projects (using [bun](https://bun.sh)):
+
+```js
+// package.json
+ "devDependencies": {
+ "del-cli": "^6.0.0",
+ "husky": "^9.1.7"
+ },
+ "scripts": {
+ "build": "bun run clean && vite build",
+ "clean": "del './build'",
+ "increment": "chronver increment",
+ "pre-commit": "bun run build && bun run increment && git add -A :/",
+ "prepare": "husky"
+ }
+```
+
+Now every time you push a commit, the `version` in `package.json` gets updated. Please note that you'll need to install the `chronver` CLI globally using the Deno method above or the path method below (recommended).
+
+### macOS/Linux
+
+You can find releases of the CLI on the [releases page](https://github.com/ChronVer/chronver/releases) of this repo.
+
+```sh
+# create personal bin directory if it doesn't exist
+mkdir -p ~/.local/bin
+
+# add to PATH in your shell profile (~/.bashrc, ~/.zshrc, etc.)
+echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
+source ~/.zshrc
+
+# move binary there
+mv chronver ~/.local/bin/
+```
+
+
+
+## Usage
+
+### Basic API
+
+```ts
+import { ChronVer } from "jsr:@chronver/chronver";
+
+// create new version with today's date
+const version = new ChronVer();
+console.log(version.toString()); // "2025.07.21"
+
+// parse existing version
+const parsed = new ChronVer("2024.04.03.1");
+console.log(parsed.year); // 2024
+console.log(parsed.month); // 4
+console.log(parsed.day); // 3
+console.log(parsed.changeset); // 1
+
+// compare versions
+const v1 = new ChronVer("2024.04.03");
+const v2 = new ChronVer("2024.04.04");
+console.log(v1.isOlderThan(v2)); // true
+console.log(v2.isNewerThan(v1)); // true
+
+// increment version
+const incremented = version.increment();
+console.log(incremented.toString()); // "2024.07.19.1" (if same day)
+```
+
+### Static Methods
+
+```ts
+// validation
+ChronVer.isValid("2024.04.03"); // true
+ChronVer.isValid("invalid"); // false
+
+// comparison
+ChronVer.compare("2024.04.03", "2024.04.04"); // -1
+
+// parsing
+const parsed = ChronVer.parseVersion("2024.04.03.1-feature");
+// {
+// changeset: 1,
+// date: "2024.04.03",
+// feature: "feature",
+// isBreaking: false,
+// version: "2024.04.03.1-feature"
+// }
+
+// sorting
+const versions = ["2024.04.05", "2024.04.03", "2024.04.04"];
+ChronVer.sort(versions); // ["2024.04.03", "2024.04.04", "2024.04.05"]
+
+// create from Date
+const date = new Date(2024, 3, 3); // April 3, 2024
+const version = ChronVer.fromDate(date, 5); // "2024.04.03.5"
+```
+
+### File Operations
+
+```ts
+// update package.json version
+const newVersion = await ChronVer.incrementInFile("package.json");
+console.log(newVersion); // "2025.07.21.1"
+
+// works with any JSON file
+await ChronVer.incrementInFile("deno.json");
+```
+
+
+
+## CLI Usage
+
+```bash
+# create new version
+chronver create # 2024.07.19
+
+# validate versions
+chronver validate "2024.04.03.1" # ✅ Valid: 2024.04.03.1
+
+# compare versions
+chronver compare "2024.04.03" "2024.04.04" # 2024.04.03 < 2024.04.04 (-1)
+
+# increment package.json
+chronver increment # 📦 Updated to: 2025.07.21.1
+chronver increment deno.json # 📦 Updated to: 2025.07.21.1
+
+# parse version details
+chronver parse "2024.04.03.1-feature"
+# 📋 Version: 2024.04.03.1-feature
+# 📅 Date: 2024.04.03
+# 🔢 Changeset: 1
+# 💥 Breaking: no
+# 🚀 Feature: feature
+# 📆 Day of week: Wednesday
+# ⏪ Released 107 days ago
+
+# sort versions
+chronver sort "2024.04.03" "2024.04.01" "2024.04.05"
+# 📊 Sorted (ascending):
+# 🔼 1. 2024.04.01
+# 🔼 2. 2024.04.03
+# 🔼 3. 2024.04.05
+
+chronver --sort-desc "2024.04.03" "2024.04.01" "2024.04.05"
+# 📊 Sorted (descending):
+# 🔽 1. 2024.04.05
+# 🔽 2. 2024.04.03
+# 🔽 3. 2024.04.01
+
+# create from specific date
+chronver format "2024-04-03" 5 # 2024.04.03.5
+
+# help
+chronver --help
+```
+
+
+
+## When to Use ChronVer
+
+### ✅ Perfect For
+
+- **SaaS platforms** with regular feature rollouts
+- **Mobile apps** with app store schedules
+- **Enterprise software** with quarterly releases
+- **Security tools** where timing matters
+- **Marketing‑driven releases** tied to campaigns
+- **Compliance software** with regulatory deadlines
+
+### ❌ Less Ideal For
+
+- **Libraries** consumed by other developers
+- **APIs** where breaking changes need clear signaling
+- **Projects** with irregular, feature‑driven releases
+- **Tools** where semantic compatibility matters more than timing
+
+
+
+## Comparison with SemVer
+
+| Aspect | ChronVer | SemVer |
+|-------------------|---------------------------------|---------------------------|
+| **Clarity** | Immediately shows when released | Requires lookup |
+| **Planning** | Aligns with calendar schedules | Feature‑driven |
+| **Communication** | "The April release" | "Version 3.2.1" |
+| **Sorting** | Chronological by default | Arbitrary without context |
+| **Compatibility** | Time‑based breaking changes | API contract based |
+| **Best for** | Time‑sensitive releases | Library compatibility |
+
+
+
+## Advanced Features
+
+### Feature Branches
+
+```ts
+const feature = new ChronVer("2024.04.03-new-ui");
+console.log(feature.feature); // "new-ui"
+console.log(feature.toString()); // "2024.04.03-new-ui"
+```
+
+### Breaking Changes
+
+```ts
+const breaking = new ChronVer("2024.04.03.1-break");
+console.log(breaking.isBreaking); // true
+```
+
+### Date Validation
+
+ChronVer validates actual calendar dates:
+
+```ts
+ChronVer.isValid("2024.02.29"); // true (2024 was a leap year)
+ChronVer.isValid("2023.02.29"); // false (2023 was not a leap year)
+ChronVer.isValid("2024.04.31"); // false (April has 30 days)
+```
+
+
+
+## Real-World Examples
+
+### `package.json` integration
+
+```json
+{
+ "name": "my-app",
+ "scripts": {
+ "version": "chronver increment"
+ },
+ "version": "2025.07.21.3"
+}
+```
+
+### CI/CD Pipeline
+
+```yaml
+# GitHub Actions example
+- name: Update version
+ run: |
+ chronver increment
+ git add package.json
+ git commit -m "chore: bump version to $(cat package.json | jq -r .version)"
+```
+
+### Release Notes
+
+```md
+## Release 2025.07.21 - Summer Feature Drop
+
+### New Features
+
+- Dark mode support
+- Mobile‑responsive dashboard
+- Advanced search filters
+
+### Bug Fixes
+
+- Fixed login timeout issue
+- Improved performance on large datasets
+
+### Breaking Changes
+
+None in this release.
+```
+
+
+
+## Development
+
+```sh
+# clone project
+git clone https://github.com/chronver/chronver.git && cd $_
+
+# lint
+deno check && deno lint
+
+# run tests
+deno test --allow-read --allow-write --fail-fast
+
+# run CLI locally
+deno run --allow-read --allow-write cli.ts --help
+```
+
+If you have [Just](https://just.systems/man/en/) installed:
+
+```sh
+just lint
+# deno check && deno lint
+
+just test
+# deno test --allow-read --allow-write --fail-fast
+
+just build
+# compile CLI to an executable
+```
+
+
+
+## Ports
+
+### Rust
+
+- https://github.com/dnaka91/chronver / https://crates.io/crates/chronver
+
+
+
+## License
+
+[Creative Commons ― CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)
+
+
+
+## FAQ
+
+### Why not just use dates?
+
+ChronVer **is** dates, but with a structured format that supports multiple releases per day, feature branches, and breaking change indicators.
+
+### What about semantic compatibility?
+
+ChronVer can indicate breaking changes with the `-break` suffix. For situations where semantic versioning is **crucial**, stick with SemVer.
+
+### How do I migrate from SemVer?
+
+1. Choose your first ChronVer date (usually next release)
+2. Update your build tools to use `chronver increment`
+3. Update documentation to explain the new format
+4. Consider keeping a mapping in your `CHANGELOG`
+
+### Can I use both ChronVer and SemVer?
+
+Absolutely! Here's how your project could use ChronVer for releases and SemVer for API versions:
+
+```json
+{
+ "apiVersion": "v2.1.0",
+ "version": "2024.07.19.1"
+}
+```