|
| 1 | +# Deno Standard Library |
| 2 | + |
| 3 | +The Deno Standard Library is a collection of high-quality packages for Deno and |
| 4 | +the web, distributed via JSR as `@std/*`. It supports multiple runtimes: Deno, |
| 5 | +Node.js, Bun, browsers, and Cloudflare Workers. |
| 6 | + |
| 7 | +## Repository Structure |
| 8 | + |
| 9 | +- Each top-level directory is a package (e.g., `async/`, `http/`, |
| 10 | + `collections/`) |
| 11 | +- `_tools/` contains internal CI/dev tooling (lint plugins, doc checkers, etc.) |
| 12 | +- Root `deno.json` defines the workspace, tasks, and compiler options |
| 13 | +- `import_map.json` maps all `@std/*` packages and dev dependencies |
| 14 | + |
| 15 | +### Package Layout |
| 16 | + |
| 17 | +Every package follows this structure: |
| 18 | + |
| 19 | +``` |
| 20 | +<package>/ |
| 21 | +├── deno.json # Name (@std/<package>), version, exports |
| 22 | +├── mod.ts # Public entry point |
| 23 | +├── <api>.ts # Implementation (one function/class per file) |
| 24 | +├── <api>_test.ts # Tests for the corresponding source file |
| 25 | +└── unstable_<api>.ts # Experimental APIs (stable packages only) |
| 26 | +``` |
| 27 | + |
| 28 | +- **Minimal exports**: each file exports a single function/class and related |
| 29 | + types |
| 30 | +- **Unstable APIs** (`unstable_*.ts`): used in packages with version >= 1.0.0; |
| 31 | + must have `@experimental` TSDoc tag; must NOT be exported from `mod.ts` |
| 32 | +- Packages with version < 1.0.0 have no unstable file restrictions |
| 33 | + |
| 34 | +## Quality Gate |
| 35 | + |
| 36 | +Run `deno task ok` before submitting. This runs: |
| 37 | + |
| 38 | +- `deno lint` (includes custom style-guide plugin at `_tools/lint_plugin.ts`) |
| 39 | +- `deno fmt --check` |
| 40 | +- `deno task test:browser` (browser compatibility check) |
| 41 | +- `deno task test` (full test suite with coverage and doc tests) |
| 42 | + |
| 43 | +Additional lint tasks available: |
| 44 | + |
| 45 | +- `deno task lint:circular` — circular dependency detection |
| 46 | +- `deno task lint:mod-exports` — validates `mod.ts` exports |
| 47 | +- `deno task lint:docs` — validates JSDoc completeness |
| 48 | +- `deno task lint:import-map` — validates import map |
| 49 | +- `deno task lint:export-names` — verifies export naming |
| 50 | +- `deno task lint:unstable-deps` — tracks unstable feature usage |
| 51 | +- `deno task typos` — spell checking |
| 52 | + |
| 53 | +## PR Conventions |
| 54 | + |
| 55 | +### Title Format |
| 56 | + |
| 57 | +PR titles must follow semantic format with a package scope: |
| 58 | + |
| 59 | +``` |
| 60 | +feat(http): add streaming response support |
| 61 | +fix(csv): handle escaped quotes correctly |
| 62 | +docs(fmt): update docstrings |
| 63 | +deprecation(encoding): base32hex |
| 64 | +``` |
| 65 | + |
| 66 | +The scope must match an existing package name. New packages must first add their |
| 67 | +name to the `scopes` list in `.github/workflows/title.yml`. |
| 68 | + |
| 69 | +### Commit Messages |
| 70 | + |
| 71 | +Follow the same semantic format as PR titles. |
| 72 | + |
| 73 | +## Testing |
| 74 | + |
| 75 | +- Framework: `Deno.test()` with `@std/assert` for assertions |
| 76 | +- Test names: descriptive, include the symbol and criteria |
| 77 | + - `delay() resolves immediately with ms = 0` |
| 78 | + - `ensureDirSync() creates dir if it does not exist` |
| 79 | +- Each source file gets a corresponding `_test.ts` file |
| 80 | +- Do NOT use `@std/assert` in implementation code — only in tests |
| 81 | + |
| 82 | +## Documentation Requirements |
| 83 | + |
| 84 | +All public symbols must have JSDoc with: |
| 85 | + |
| 86 | +1. Short description |
| 87 | +2. `@typeParam` for each type parameter |
| 88 | +3. `@param` for each parameter |
| 89 | +4. `@returns` for return value |
| 90 | +5. At least one `@example` with a title and runnable code snippet |
| 91 | + |
| 92 | +Example snippets must be reproducible and use `@std/assert` assertions. Use |
| 93 | +`ignore` directive to skip running a snippet, `expect-error` for expected |
| 94 | +failures. |
| 95 | + |
| 96 | +Module files (`mod.ts`) need a `@module` tag. |
| 97 | + |
| 98 | +## Error Message Style |
| 99 | + |
| 100 | +- Sentence case, no trailing period |
| 101 | +- Active voice: "Cannot parse input x" not "Input x cannot be parsed" |
| 102 | +- No contractions: "Cannot" not "Can't" |
| 103 | +- Quote string values: `Cannot parse input "hello, world"` |
| 104 | +- Use colons for context: `Cannot parse input x: value is empty` |
| 105 | +- State current and desired state when possible |
| 106 | + |
| 107 | +Exception: `@std/assert` uses periods in error messages (downstream compat). |
| 108 | + |
| 109 | +## CI Pipeline |
| 110 | + |
| 111 | +Tests run on Ubuntu, Windows, and macOS against Deno v1.x, v2.x, and canary. |
| 112 | +Cross-runtime testing includes Node.js and Bun. Timezone-sensitive tests run |
| 113 | +across Sydney, London, and Toronto. |
| 114 | + |
| 115 | +## Versioning and Releases |
| 116 | + |
| 117 | +- Packages >= 1.0.0: follow semver |
| 118 | +- Packages < 1.0.0: follow semver proposal |
| 119 | + (https://github.com/semver/semver/pull/923) |
| 120 | +- Release tags: `release-YYYY.MM.DD` |
| 121 | +- Publishing: `workspace_publish` workflow pushes to JSR |
| 122 | + |
| 123 | +## Deprecation Policy |
| 124 | + |
| 125 | +Deprecated APIs use the format: |
| 126 | + |
| 127 | +```ts |
| 128 | +/** |
| 129 | + * @deprecated This will be removed in X.Y.Z. Use {@linkcode bar} instead. |
| 130 | + */ |
| 131 | +``` |
| 132 | + |
| 133 | +Deprecated symbols are removed in the next major version. PRs use the title |
| 134 | +format `deprecation(<package>): <symbol>`. |
0 commit comments