skills/bun-quickstart/SKILL.md
Build your first app with Bun
npx skillsauth add jarle/bun-skills Bun QuickstartInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Build your first app with Bun
Build a minimal HTTP server with Bun.serve, run it locally, then evolve it by installing a package.
<Info>Prerequisites: Bun installed and available on your PATH. See installation for setup.</Info>
```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun init my-app
```
It'll prompt you to pick a template, either `Blank`, `React`, or `Library`. For this guide, we'll pick `Blank`.
```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun init my-app
```
```txt theme={"theme":{"light":"github-light","dark":"dracula"}}
✓ Select a project template: Blank
- .gitignore
- CLAUDE.md
- .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc -> CLAUDE.md
- index.ts
- tsconfig.json (for editor autocomplete)
- README.md
```
This automatically creates a `my-app` directory with a basic Bun app.
</Step>
<Step title="Step 2">
Run the `index.ts` file using `bun run index.ts`.
```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
cd my-app
bun run index.ts
```
```txt theme={"theme":{"light":"github-light","dark":"dracula"}}
Hello via Bun!
```
You should see a console output saying `"Hello via Bun!"`.
</Step>
<Step title="Step 3">
Replace the contents of `index.ts` with the following code:
```ts index.ts icon="https://mintcdn.com/bun-1dd33a4e/nIz6GtMH5K-dfXeV/icons/typescript.svg?fit=max&auto=format&n=nIz6GtMH5K-dfXeV&q=85&s=5d73d76daf7eb7b158469d8c30d349b0" theme={"theme":{"light":"github-light","dark":"dracula"}}
const server = Bun.serve({
port: 3000,
routes: {
"/": () => new Response('Bun!'),
}
});
console.log(`Listening on ${server.url}`);
```
Run the `index.ts` file again using `bun run index.ts`.
```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun run index.ts
```
```txt theme={"theme":{"light":"github-light","dark":"dracula"}}
Listening on http://localhost:3000
```
Visit [`http://localhost:3000`](http://localhost:3000) to test the server. You should see a simple page that says `"Bun!"`.
<Accordion title="Seeing TypeScript errors on Bun?">
If you used `bun init`, Bun will have automatically installed Bun's TypeScript declarations and configured your `tsconfig.json`. If you're trying out Bun in an existing project, you may see a type error on the `Bun` global.
To fix this, first install `@types/bun` as a dev dependency.
```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun add -d @types/bun
```
Then add the following to your `compilerOptions` in `tsconfig.json`:
```json tsconfig.json icon="file-json" theme={"theme":{"light":"github-light","dark":"dracula"}}
{
"compilerOptions": {
"lib": ["ESNext"],
"target": "ESNext",
"module": "Preserve",
"moduleDetection": "force",
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"noEmit": true
}
}
```
</Accordion>
</Step>
<Step title="Step 4">
Install the `figlet` package and its type declarations. Figlet is a utility for converting strings into ASCII art.
```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun add figlet
bun add -d @types/figlet # TypeScript users only
```
Update `index.ts` to use `figlet` in `routes`.
```ts index.ts icon="https://mintcdn.com/bun-1dd33a4e/nIz6GtMH5K-dfXeV/icons/typescript.svg?fit=max&auto=format&n=nIz6GtMH5K-dfXeV&q=85&s=5d73d76daf7eb7b158469d8c30d349b0" theme={"theme":{"light":"github-light","dark":"dracula"}}
import figlet from 'figlet'; // [!code ++]
const server = Bun.serve({
port: 3000,
routes: {
"/": () => new Response('Bun!'),
"/figlet": () => { // [!code ++]
const body = figlet.textSync('Bun!'); // [!code ++]
return new Response(body); // [!code ++]
} // [!code ++]
}
});
console.log(`Listening on ${server.url}`);
```
Run the `index.ts` file again using `bun run index.ts`.
```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun run index.ts
```
```txt theme={"theme":{"light":"github-light","dark":"dracula"}}
Listening on http://localhost:3000
```
Visit [`http://localhost:3000/figlet`](http://localhost:3000/figlet) to test the server. You should see a simple page that says `"Bun!"` in ASCII art.
```txt theme={"theme":{"light":"github-light","dark":"dracula"}}
____ _
| __ ) _ _ _ __ | |
| _ \| | | | '_ \| |
| |_) | |_| | | | |_|
|____/ \__,_|_| |_(_)
```
</Step>
<Step title="Step 5">
Let's add some HTML. Create a new file called `index.html` and add the following code:
```html index.html icon="file-code" theme={"theme":{"light":"github-light","dark":"dracula"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bun</title>
</head>
<body>
<h1>Bun!</h1>
</body>
</html>
```
Then, import this file in `index.ts` and serve it from the root `/` route.
```ts index.ts icon="https://mintcdn.com/bun-1dd33a4e/nIz6GtMH5K-dfXeV/icons/typescript.svg?fit=max&auto=format&n=nIz6GtMH5K-dfXeV&q=85&s=5d73d76daf7eb7b158469d8c30d349b0" theme={"theme":{"light":"github-light","dark":"dracula"}}
import figlet from 'figlet';
import index from './index.html'; // [!code ++]
const server = Bun.serve({
port: 3000,
routes: {
"/": index, // [!code ++]
"/figlet": () => {
const body = figlet.textSync('Bun!');
return new Response(body);
}
}
});
console.log(`Listening on ${server.url}`);
```
Run the `index.ts` file again using `bun run index.ts`.
```bash terminal icon="terminal" theme={"theme":{"light":"github-light","dark":"dracula"}}
bun run index.ts
```
```txt theme={"theme":{"light":"github-light","dark":"dracula"}}
Listening on http://localhost:3000
```
Visit [`http://localhost:3000`](http://localhost:3000) to test the server. You should see the static HTML page.
</Step>
</Steps>
🎉 Congratulations! You've built a simple HTTP server with Bun and installed a package.
Bun can also execute "scripts" from your package.json. Add the following script:
{
"name": "quickstart",
"module": "index.ts",
"type": "module",
"private": true,
"scripts": { // [!code ++]
"start": "bun run index.ts" // [!code ++]
}, // [!code ++]
"devDependencies": {
"@types/bun": "latest"
},
"peerDependencies": {
"typescript": "^5"
}
}
Then run it with bun run start.
bun run start
Listening on http://localhost:3000
<Note>⚡️ Performance — bun run is roughly 28x faster than npm run (6ms vs 170ms of overhead).</Note>
development
Using TypeScript with Bun, including type definitions and compiler options
development
Learn how to write tests using Bun's Jest-compatible API with support for async tests, timeouts, and various test modifiers
testing
Learn how to use snapshot testing in Bun to save and compare output between test runs
testing
Learn about Bun test's runtime integration, environment variables, timeouts, and error handling