Skip to content

Commit 110e77c

Browse files
committed
feat: docs improvements and bechmarks
1 parent 43033c2 commit 110e77c

4 files changed

Lines changed: 332 additions & 118 deletions

File tree

AGENTS.md

Lines changed: 165 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,191 @@
1+
# AGENTS.md
12

2-
Default to using Bun instead of Node.js.
3+
Guidelines for AI coding agents working in this repository.
34

4-
- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
5-
- Use `bun test` instead of `jest` or `vitest`
6-
- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
7-
- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
8-
- Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
9-
- Use `bunx <package> <command>` instead of `npx <package> <command>`
10-
- Bun automatically loads .env, so don't use dotenv.
5+
## Project Overview
116

12-
## APIs
7+
This is a CLI tool that converts Next.js static exports into a single HTML file with hash-based routing. It inlines all assets (CSS, JS, images) into one portable HTML file.
138

14-
- `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`.
15-
- `bun:sqlite` for SQLite. Don't use `better-sqlite3`.
16-
- `Bun.redis` for Redis. Don't use `ioredis`.
17-
- `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`.
18-
- `WebSocket` is built-in. Don't use `ws`.
19-
- Prefer `Bun.file` over `node:fs`'s readFile/writeFile
20-
- Bun.$`ls` instead of execa.
9+
## Build, Test, and Lint Commands
2110

22-
## Testing
11+
```bash
12+
# Run all tests
13+
bun test
2314

24-
Use `bun test` to run tests.
15+
# Run a single test file
16+
bun test src/bundle.test.ts
2517

26-
```ts#index.test.ts
27-
import { test, expect } from "bun:test";
18+
# Run tests matching a pattern
19+
bun test -t "test name pattern"
2820

29-
test("hello world", () => {
30-
expect(1).toBe(1);
31-
});
21+
# Build the CLI
22+
bun run build
23+
24+
# Run the converter locally
25+
bun run ./index.ts <path-to-nextjs-export>
3226
```
3327

34-
## Frontend
35-
36-
Use HTML imports with `Bun.serve()`. Don't use `vite`. HTML imports fully support React, CSS, Tailwind.
37-
38-
Server:
39-
40-
```ts#index.ts
41-
import index from "./index.html"
42-
43-
Bun.serve({
44-
routes: {
45-
"/": index,
46-
"/api/users/:id": {
47-
GET: (req) => {
48-
return new Response(JSON.stringify({ id: req.params.id }));
49-
},
50-
},
51-
},
52-
// optional websocket support
53-
websocket: {
54-
open: (ws) => {
55-
ws.send("Hello, world!");
56-
},
57-
message: (ws, message) => {
58-
ws.send(message);
59-
},
60-
close: (ws) => {
61-
// handle close
62-
}
63-
},
64-
development: {
65-
hmr: true,
66-
console: true,
67-
}
68-
})
28+
Note: This project does not have a lint command configured. The test-next-app workspace has `bun run lint` which runs ESLint on that subproject.
29+
30+
## Code Style Guidelines
31+
32+
### Imports
33+
34+
```ts
35+
// Use import type for type-only imports
36+
import type { Route, ParsedOutput } from "./types";
37+
38+
// Node.js built-ins use node: prefix
39+
import { readFile, readdir } from "node:fs/promises";
40+
import { join, relative } from "node:path";
41+
42+
// Bun APIs (no imports needed for built-in Bun globals)
43+
// Use Bun.$ for shell commands
44+
// Use Bun.write for file output
45+
// Use Bun.file for reading files
6946
```
7047

71-
HTML files can import .tsx, .jsx or .js files directly and Bun's bundler will transpile & bundle automatically. `<link>` tags can point to stylesheets and Bun's CSS bundler will bundle.
48+
### TypeScript Configuration
49+
50+
- Strict mode enabled with additional checks
51+
- `verbatimModuleSyntax: true` - requires explicit `import type`
52+
- `noUncheckedIndexedAccess: true` - array/object access may be undefined
53+
- `noFallthroughCasesInSwitch: true`
54+
- `noImplicitOverride: true`
55+
- Target: ESNext, Module: Preserve
7256

73-
```html#index.html
74-
<html>
75-
<body>
76-
<h1>Hello, world!</h1>
77-
<script type="module" src="./frontend.tsx"></script>
78-
</body>
79-
</html>
57+
### Types and Interfaces
58+
59+
- Use `interface` for object types, not `type`
60+
- Use `Map<K, V>` for key-value collections
61+
- Export interfaces from a central `types.ts` file
62+
63+
```ts
64+
// Preferred
65+
export interface Route {
66+
path: string;
67+
html: string;
68+
}
69+
70+
// Avoid
71+
export type Route = {
72+
path: string;
73+
html: string;
74+
};
8075
```
8176

82-
With the following `frontend.tsx`:
77+
### Functions
78+
79+
- Use camelCase for function and variable names
80+
- Use async/await for asynchronous operations
81+
- Return typed Promises explicitly when helpful
8382

84-
```tsx#frontend.tsx
85-
import React from "react";
86-
import { createRoot } from "react-dom/client";
83+
```ts
84+
export async function parseRoutes(outputDir: string): Promise<ParsedOutput> {
85+
// implementation
86+
}
87+
```
8788

88-
// import .css files directly and it works
89-
import './index.css';
89+
### Error Handling
9090

91-
const root = createRoot(document.body);
91+
- Throw `Error` objects with descriptive messages
92+
- Validate inputs at function boundaries
9293

93-
export default function Frontend() {
94-
return <h1>Hello, world!</h1>;
94+
```ts
95+
if (!routes.length) {
96+
throw new Error("No routes found in the Next.js export");
9597
}
98+
```
99+
100+
### Code Formatting
101+
102+
- No comments in production code (code should be self-documenting)
103+
- Use template literals for multi-line strings and HTML generation
104+
- Use `$` template tag for shell commands: `await Bun.$`echo hello``
105+
106+
### Testing
107+
108+
- Use `bun:test` framework
109+
- Place tests adjacent to source files with `.test.ts` suffix
110+
- Use `beforeAll` for expensive setup (e.g., building test fixtures)
111+
- Use `expect` assertions from bun:test
96112

97-
root.render(<Frontend />);
113+
```ts
114+
import { test, expect, beforeAll } from "bun:test";
115+
116+
test("description of what is being tested", async () => {
117+
const result = await functionUnderTest();
118+
expect(result).toBe(expected);
119+
});
120+
```
121+
122+
### File Operations
123+
124+
- Prefer Bun APIs over Node.js equivalents
125+
- Use `Bun.file()` for reading, `Bun.write()` for writing
126+
- Use `node:fs/promises` for directory operations (readdir, mkdir)
127+
128+
```ts
129+
// Reading a file
130+
const content = await Bun.file(path).text();
131+
132+
// Writing a file
133+
await Bun.write(outputPath, content);
134+
135+
// Directory operations
136+
import { readdir, mkdir } from "node:fs/promises";
137+
const files = await readdir(dir);
98138
```
99139

100-
Then, run index.ts
140+
### Shell Commands
141+
142+
```ts
143+
// Use Bun.$ for shell commands
144+
await Bun.$`bun run build`;
101145

102-
```sh
103-
bun --hot ./index.ts
146+
// With working directory
147+
await Bun.$`bun run build`.cwd(projectDir);
104148
```
105149

106-
For more information, read the Bun API docs in `node_modules/bun-types/docs/**.mdx`.
150+
## Bun Runtime Guidelines
151+
152+
Default to using Bun instead of Node.js.
153+
154+
- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
155+
- Use `bun test` instead of `jest` or `vitest`
156+
- Use `bun build` instead of `webpack` or `esbuild`
157+
- Use `bun install` instead of `npm install` or `yarn install`
158+
- Use `bun run <script>` instead of `npm run <script>`
159+
- Use `bunx <package> <command>` instead of `npx <package> <command>`
160+
- Bun automatically loads .env files; don't use dotenv
161+
162+
### Bun APIs
163+
164+
- `Bun.serve()` for HTTP servers (don't use express)
165+
- `bun:sqlite` for SQLite (don't use better-sqlite3)
166+
- `Bun.redis` for Redis (don't use ioredis)
167+
- `Bun.sql` for Postgres (don't use pg or postgres.js)
168+
- `WebSocket` is built-in (don't use ws package)
169+
- Prefer `Bun.file` over `node:fs` readFile/writeFile
170+
- `Bun.$` for shell commands (instead of execa)
171+
172+
## Project Structure
173+
174+
```
175+
/
176+
├── index.ts # CLI entry point
177+
├── src/
178+
│ ├── bundler.ts # Main bundling logic
179+
│ ├── parser.ts # Parse Next.js export structure
180+
│ ├── router.ts # Generate client-side router shim
181+
│ ├── inliner.ts # Inline CSS/JS/images into HTML
182+
│ ├── types.ts # Shared TypeScript interfaces
183+
│ └── *.test.ts # Test files adjacent to source
184+
└── test-next-app/ # Test fixture Next.js app
185+
```
186+
187+
## Important Notes
188+
189+
- This tool targets static Next.js exports (output from `next build` + `next export` or `output: export`)
190+
- The generated HTML uses hash-based routing for client-side navigation
191+
- All assets are inlined as base64 data URLs or inline scripts/styles

0 commit comments

Comments
 (0)