| title | bun create |
|---|---|
| description | Create a new Bun project from a React component, a `create-<template>` npm package, a GitHub repo, or a local template |
Template a new Bun project with bun create. It creates a project from a React component, a create-<template> npm package, a GitHub repo, or a local template.
To create an empty project, use bun init.
bun create ./MyComponent.tsx turns an existing React component into a complete dev environment with hot reload and production builds in one command.
bun create ./MyComponent.jsx # .tsx also supportedWhen you run bun create <component>, Bun:
- Uses Bun's JavaScript bundler to analyze your module graph.
- Collects all the dependencies needed to run the component.
- Scans the exports of the entry point for a React component.
- Generates a
package.jsonfile with the dependencies and scripts needed to run the component. - Installs any missing dependencies using
bun install --only-missing. - Generates the following files:
${component}.html${component}.client.tsx(entry point for the frontend)${component}.css
- Starts a frontend dev server.
TailwindCSS is a utility-first CSS framework for styling web applications.
When you run bun create <component>, Bun scans your JSX/TSX file (and any files it imports) for TailwindCSS class names. If Bun detects TailwindCSS class names, it adds the following dependencies to your package.json:
{
"dependencies": {
"tailwindcss": "^4",
"bun-plugin-tailwind": "latest"
}
}Bun also configures bunfig.toml to use its TailwindCSS plugin with Bun.serve():
[serve.static]
plugins = ["bun-plugin-tailwind"]Bun also writes a ${component}.css file with @import "tailwindcss"; at the top:
@import "tailwindcss";shadcn/ui is a component library tool for building web applications.
bun create <component> scans for any shadcn/ui components imported from @/components/ui.
If it finds any, it runs:
# Assuming bun detected imports to @/components/ui/accordion and @/components/ui/button
bunx shadcn@canary add accordion button # and any other componentsSince shadcn/ui itself uses TailwindCSS, bun create also adds the TailwindCSS dependencies to your package.json and configures bunfig.toml to use Bun's TailwindCSS plugin with Bun.serve(), as described earlier.
bun create also sets up:
tsconfig.jsonto alias"@/*"to"src/*"or.(depending on whether there is asrc/directory)components.jsonso that shadcn/ui knows it's a shadcn/ui projectstyles/globals.cssfile that configures Tailwind v4 the way shadcn/ui expects${component}.build.tsfile that builds the component for production withbun-plugin-tailwindconfigured
Use bun create ./MyComponent.jsx to run code generated by LLMs like Claude or ChatGPT locally.
bun create <template> [<destination>]If you don't have a local template with the same name, this command downloads and runs the create-<template> package from npm. These two commands are equivalent:
bun create remix
bunx create-remixRefer to the create-<template> package's documentation for usage instructions. For react and next, Bun doesn't run a package; it only prints a message pointing to react-app/vite and next-app.
bun create <user>/<repo> downloads the contents of the GitHub repo to disk.
bun create <user>/<repo>
bun create github.com/<user>/<repo>Optionally specify a name for the destination folder. If you don't, Bun uses the repo name.
bun create <user>/<repo> mydir
bun create github.com/<user>/<repo> mydirBun then:
- Downloads the template
- Copies all template files into the destination folder
- Installs dependencies with
bun install - Initializes a fresh Git repo. Opt out with the
--no-gitflag.
By default Bun does not overwrite existing files. Use the --force flag to overwrite them.
You can define custom templates on your local file system. Put them in one of the following directories:
$HOME/.bun-create/<name>: global templates<project root>/.bun-create/<name>: project-specific templates
Set the BUN_CREATE_DIR environment variable to change the global template path.
To create a local template, create a directory in $HOME/.bun-create named after your template.
cd $HOME/.bun-create
mkdir foo
cd fooThen, create a package.json file in that directory with the following contents:
{
"name": "foo"
}Run bun create foo elsewhere on your file system to verify that Bun finds your local template.
You can specify pre- and post-install setup scripts in the "bun-create" section of your local template's package.json.
{
"name": "@bun-examples/simplereact",
"version": "0.0.1",
"main": "index.js",
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"bun-create": {
"preinstall": "echo 'Installing...'", // a single command
"postinstall": ["echo 'Done!'"], // an array of commands
"start": "bun run echo 'Hello world!'"
}
}preinstall and postinstall accept a string or an array of strings. An array of commands runs in order.
| Field | Description |
|---|---|
postinstall |
runs after installing dependencies |
preinstall |
runs before installing dependencies |
start |
the command Bun prints under "To get started, run:" when it finishes; defaults to bun dev |
After cloning a template, bun create removes the "bun-create" section from package.json before writing it to the destination folder.
| Flag | Description |
|---|---|
--force |
Overwrite existing files |
--no-install |
Skip installing node_modules & tasks |
--no-git |
Don't initialize a git repository |
--open |
Start & open in-browser after finish |
| Name | Description |
|---|---|
GITHUB_API_DOMAIN |
The GitHub domain Bun downloads from. Set this if you use GitHub Enterprise or a proxy |
GITHUB_TOKEN (or GITHUB_ACCESS_TOKEN) |
Lets bun create access private repositories and avoid rate limits. Bun picks GITHUB_TOKEN over GITHUB_ACCESS_TOKEN if both exist. |
<Accordion title={How bun create works}>
When you run bun create ${template} ${destination}, here’s what happens:
IF remote template (elysia, elysia-buchta, or stric; Bun hands any other npm template name to bunx create-${template} instead, except react and next, for which it only prints a message pointing to react-app/vite and next-app)
- GET
registry.npmjs.org/@bun-examples/${template}/latestand parse it - GET
registry.npmjs.org/@bun-examples/${template}/-/${template}-${latestVersion}.tgz - Decompress & extract
${template}-${latestVersion}.tgzinto${destination}- If files would be overwritten, warn and exit unless you pass
--force
- If files would be overwritten, warn and exit unless you pass
IF GitHub repo
- Download the tarball from GitHub’s API
- Decompress & extract into
${destination}- If files would be overwritten, warn and exit unless you pass
--force
- If files would be overwritten, warn and exit unless you pass
ELSE IF local template
- Open local template folder
- Delete destination directory recursively
- Copy files recursively using the fastest system calls available (on macOS,
fcopyfile; on Linux,copy_file_range). Do not copy or traverse into thenode_modulesfolder if it exists (this alone makes it faster thancp)
THEN, for remote templates, GitHub repos, and local templates alike:
- Parse the
package.json(again!), updatenameto be${basename(destination)}, remove thebun-createsection from thepackage.jsonand save the updatedpackage.jsonto disk. - Run any tasks defined in
"bun-create": { "preinstall" } - Run
bun installunless you pass--no-installOR no dependencies are in package.json - Run any tasks defined in
"bun-create": { "postinstall" } - Run
git init; git add -A .; git commit -am "Initial Commit";- Rename
gitignoreto.gitignore. npm strips.gitignorefiles from published packages. - If there are dependencies, this step runs in a separate thread concurrently while Bun installs node_modules
- We tested using libgit2 if available, and it performed 3x slower in microbenchmarks
- Rename