Skip to content
Run BunYour friendly Bun playground
Canary build: these docs may describe unreleased changes. Read this page on docs.runbun.dev

Features

  • Syntax-highlighted editor with themes and light/dark mode
  • File tree with search and a “New file” button
  • Tabs for open files: close with the × button, Delete, or Ctrl/Cmd+W
  • Auto-save (on by default): edits are saved a moment after you stop typing. Switch it off in the tab bar to save with Ctrl/Cmd+S instead; unsaved tabs show a dot, and Run, Install, bun test and Share save everything first. The setting applies to every project and every open playground tab.
  • Format in the tab bar (Shift+Alt+F) formats the open file with bun fmt, as one undoable edit (see Toolchain)
  • Type errors in TypeScript files, a name’s type and documentation when the pointer rests on it, and completions as you type, from TypeScript 7’s checker (see Toolchain). The list opens after ., in import paths, and at the first letter of a name; ↑/↓ pick, Enter or Tab insert, Esc closes it. The selected entry’s type and docs show under the list. Names exported by the project’s other files, installed packages and Bun’s and Node’s built-in modules (bun:sqlite, node:fs) are offered too, with the module they come from, and inserting one adds its import. Typing ( or , in a call shows its parameter hints above the line, with the current parameter underlined; ↑/↓ step through overloads and Esc hides them.
  • Resizable panes
  • Run status as a pill in the status bar (default) or a toast over the panes that fades a few seconds after the program settles; errors stay until the next change. Pick one under Appearance.
  • Status bar along the bottom: buttons to show or hide the file tree, the preview and the console (with both of those hidden, the editor takes their room), what the program is doing, and for the open file its error and warning counts (click to go to the next one), the cursor’s line and column, and its language (for TypeScript, with the version the type checker follows), and the keyboard shortcuts. The Bun version links to Bun compatibility.
  • Open folder or Open zip file loads a project from your computer (skips node_modules and .git). A zip whose files all sit in one folder, like GitHub’s downloads, opens that folder.
  • In Chrome and Edge, an opened folder stays linked: edits, new files and deletions are saved to it on disk. node_modules stays in the browser and the folder’s own node_modules and .git aren’t touched. A reload opens it again if the browser still allows access; otherwise pick Reopen in the project picker, which asks once more. Other browsers open a copy.

Not yet: renaming or deleting files from the tree. Very large files are slow, because every line is rendered.

ShortcutDoes
Ctrl/Cmd+EnterRun
Ctrl/Cmd+.Stop the server
Ctrl/Cmd+SSave the file
Shift+Alt+FFormat the file with bun fmt (format)
Ctrl/Cmd+IShow the type and docs of the name at the cursor (showHover); any key closes it
Ctrl+SpaceShow completions at the cursor (suggest; Ctrl on macOS too)
Ctrl/Cmd+Shift+SpaceShow the parameters of the call at the cursor (signatureHelp)
Ctrl/Cmd+W, DeleteClose the focused tab
Ctrl/Cmd+BShow or hide the file tree
Ctrl/Cmd+JShow or hide the console
Ctrl/Cmd+KShow or hide the preview
EscLeave the expanded preview

They work in the preview page too. To change them, open the keyboard button (in the header or the status bar) and write overrides as JSON: a command name to a chord, a list of chords, or null to turn it off, e.g. { "run": ["Mod+Enter", "Alt+R"], "togglePreview": null }. Mod is Cmd on macOS and Ctrl elsewhere; the other modifiers are Ctrl, Alt, Shift and Meta, and the space bar is Space. Overrides are kept in this browser for every project, and open playground tabs pick up changes right away.

A terminal with colors, clickable links, history (↑/↓) and line editing (Ctrl+A/E/U). Ctrl+C on an empty line stops the server; Ctrl+L clears.

CommandDoes
bun run <script|file>, bun <file>Run a package.json script or a file
bun test [filter…]Run *.test.* / *.spec.* files with bun:test
bun install (i)Install dependencies
bun add <pkg[@range]> [-d] (a)Add a dependency
bun remove <pkg> (rm)Remove a dependency
bun fmt [-c] [path…]Format files like Prettier, or only check them (-c)
ls [dir], cat <file>List a folder, print a file
cookies [clear]List or clear the preview’s cookies
resetThrow away your changes and reload the project from its source
clear, help

The console is not a full shell: no quotes, pipes, &&, bunx, or file commands like mkdir and mv.

Run starts your code in a Web Worker. It runs the first of:

  1. module or main in package.json
  2. the file in scripts.dev or scripts.start ("dev": "bun --watch src/index.ts" works)
  3. index.ts, index.tsx, index.js or src/index.ts
  • Press Run (Ctrl/Cmd+Enter) again to restart. Stop with Ctrl/Cmd+., or Ctrl+C in the console.
  • Edits reach the running code: the next import or request sees them, and fs.watch fires. The server isn’t restarted automatically: --watch and --hot are ignored.
  • Scripts must have the form bun <file>. Scripts like vite, astro dev or tsc && … can’t run; start those tools from a file instead (see Frameworks).

When your code starts a server (Bun.serve, node:http, or export default { fetch }), the preview shows it.

  • Request bar: send any method, path and body. The body is written in the same editor as files, highlighted as JSON, and each preview tab keeps its own. HTML responses open in the page; anything else shows status, headers and the body: JSON formatted, and JSON, HTML, CSS, JavaScript, XML and Markdown highlighted.
  • Tabs: several previews at once.
  • Open in a new tab: the page gets its own browser tab, still served by the playground (keep the playground tab open).
  • Requests stay inside: fetch("/api/x"), links, forms and redirects from the preview page reach your server.
  • WebSockets: the preview page’s WebSocket connects to your server (Bun.serve upgrade, node:http upgrade, the ws package). localhost:<port> URLs pick the server on that port.
  • Streaming: streamed responses and Server-Sent Events arrive as they’re sent.
  • Cookies: kept across restarts; see them with cookies.
  • HTML imports: import page from "./index.html" in Bun.serve routes is bundled with Bun’s bundler.
  • The preview follows the playground’s light/dark mode.

Limits: the server isn’t reachable from outside the browser, there’s no HTTP caching (conditional requests are dropped), and only the preview page can open WebSockets to it.

Dependencies install automatically when a project opens with missing packages. bun install uses bun.lock when there is one. Details and limits are in Toolchain.

  • Saved as you type, in your browser. See Storage and persistence.
  • Share: the Share menu copies a link with the whole project in the URL (nothing is uploaded), a Markdown badge, or HTML. node_modules, .git, binary files and secrets (.env, keys, .npmrc) are left out. Very long links can be shortened to runbun.dev/s/<id>, which stores a copy on runbun.dev (see Privacy). Download as zip saves every file except node_modules and .git, binaries included.
  • GitHub: open any public repo, branch or subfolder from the project picker or with ?repo=. Up to 500 files; GitHub allows 60 imports an hour per IP.
  • Examples: Elysia, Hono, Astro + Solid, Vite, Lit SSR and more in the project picker.
  • One tab per project: a second tab with the same project can’t save its changes.

Any project can be put in another page, as a <bun-playground> element or an iframe. See Embedding and the embed reference.

URLOpens
runbun.devThe demo project
?example=<name>A bundled example, e.g. ?example=elysia-demo
?repo=owner/repoA GitHub repo. Also owner/repo@ref, a github.com URL, or …/tree/<ref>/<dir>
#code=…A shared project
/s/<id>A short share link

Your saved changes win over the link’s source; use reset to start over from it.

?vars= sets the overlay drawn over the whole page, for this visit only: Share links drop it and the next visit doesn’t remember it. It takes a JSON object with base (both schemes) and optionally light or dark, each with --overlay (a wash) and --overlay-ring (a 1px border), e.g. ?vars={"base":{"--overlay-ring":"linear-gradient(135deg,%23f9d6e3,%23a8cdf0)"}}. Other names are ignored, and a value may only use colors, none, and the functions linear-gradient, radial-gradient, conic-gradient (and their repeating- forms), rgb, rgba, hsl, hsla, hwb, lab, lch, oklab, oklch, color, color-mix, light-dark and calc; no images or var(). none or "" turns off the theme’s own overlay (the Elysia family has one). An embed doesn’t draw this overlay; style bun-playground::part(overlay) on the host page instead (see the embed reference).