aRustyDev / aRustyDev/mdbook-htmx
docs(adr): ADR-0011: TypeScript for Reference Implementation Scripts
- Dominant language
- Rust
- Stars
- 0
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
# ADR-0011: TypeScript for Reference Implementation Scripts
## Status
Accepted
## Context
ADR-0010 establishes that mdbook-htmx generates server-side reference scripts. This ADR addresses the language choice: TypeScript vs JavaScript.
## Decision Drivers
1. **Self-Documentation** - Types describe manifest schema without separate docs
2. **Error Prevention** - Catch type mismatches at compile time
3. **IDE Support** - Autocomplete, refactoring, go-to-definition
4. **Runtime Compatibility** - Must work in Workers, Node, Deno, Bun
5. **User Accessibility** - Not all users know TypeScript
## Options Considered
### Option A: JavaScript Only
Plain JavaScript with JSDoc comments for types.
```javascript
/**
* @param {import('./types').User | null} user
* @param {import('./types').Page} page
* @returns {boolean}
*/
function isAuthorized(user, page) {
return page.auth.access === 'public' || user !== null;
}
```
**Pros:**
- No build step
- Universally understood
- Runs directly in Node
**Cons:**
- Types are comments, not enforced
- Verbose JSDoc for complex types
- Less IDE support than native TS
### Option B: TypeScript (Recommended)
TypeScript with explicit types.
```typescript
import type { User, Page } from './types';
function isAuthorized(user: User | null, page: Page): boolean {
return page.auth.access === 'public' || user !== null;
}
```
**Pros:**
- Types are enforced
- Self-documenting
- Excellent IDE support
- Catches errors before runtime
- Industry standard for server-side code
**Cons:**
- Requires build step
- Learning curve for some users
### Option C: Both (Generate TS, Transpile to JS)
Generate TypeScript, also include transpiled JavaScript.
```
book/htmx/scripts/
├── src/ # TypeScript source
│ └── *.ts
├── dist/ # Transpiled JavaScript
│ └── *.js
└── types/ # Declaration files
└── *.d.ts
```
**Pros:**
- TypeScript users get native TS
- JavaScript users get working code
- Type definitions available for both
**Cons:**
- Larger output
- Two versions to maintain conceptually
## Decision
**TypeScript as default, with JavaScript output option.**
Default configuration:
```toml
[output.htmx.scripts]
language = "typescript"
emit-js = false # Also emit transpiled JS
emit-declarations = true # Emit .d.ts files
```
Users can set `language = "javascript"` for plain JS output with JSDoc.
## Rationale
1. **Types Document the Manifest**
```typescript
// Types ARE the documentation
interface Page {
auth: {
access: 'public' | 'authenticated' | 'roles';
roles?: string[];
};
}
```
Users reading the code understand the manifest structure without separate docs.
2. **Cloudflare Workers Natively Supports TypeScript**
```bash
# wrangler handles TypeScript automatically
wrangler deploy
```
No separate build step for the primary deployment target.
3. **Error Prevention**
```typescript
// Caught at compile time
if (page.auth.access === 'admin') { // Error: 'admin' not in union type
```
4. **Modern Standard**
TypeScript is the de facto standard for:
- Cloudflare Workers
- Deno (native support)
- Node.js server applications
- Most modern web frameworks
## Bundle Size Considerations
TypeScript transpiles to JavaScript with **zero runtime overhead**:
| Metric | TypeScript | Transpiled JS |
|--------|------------|---------------|
| Bundle size | N/A (source) | Same as hand-written JS |
| Runtime perf | N/A | Identical |
| Types at runtime | Erased | None |
The `type` imports are completely removed:
```typescript
// Source
import type { Page } from './types';
// Transpiled - import disappears
```
## Configuration
```toml
[output.htmx.scripts]
enabled = true
language = "typescript" # typescript | javascript
# TypeScript options
target = "es2022" # ECMAScript target
module = "esm" # esm | commonjs
strict = true # Strict type checking
emit-js = false # Also generate .js files
emit-declarations = true # Generate .d.ts files
```
## Consequences
### Positive
- Types serve as schema documentation
- Compile-time error catching
- Better IDE experience
- Industry-standard choice
- Native Workers/Deno support
### Negative
- Some users unfamiliar with TypeScript
- Build step required for Node.js (unless using ts-node)
### Mitigation
- Include transpiled JS as option (`emit-js = true`)
- Provide tsconfig.json with recommended settings
- Document common TypeScript patterns
## References
- [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/)
- [Cloudflare Workers TypeScript](https://developers.cloudflare.com/workers/languages/typescript/)
- [Deno TypeScript Support](https://deno.land/manual/typescript)
- [Type-Only Imports](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export)
Contributor guide
Assessment
This issue has not been assessed yet.