Building your app for production happens through one build.
It takes the following arguments (see the CLI reference for every command):
npx one build [options]
--platform web|ios|android # what to build (default: web)--only <pattern> # limit the pages built to a micromatch pattern--step <name> # run a single internal build step--skip-env # skip loading .env files during buildTo build for iOS for example, you would run:
npx one build --platform iosWhen building One for web, the output will be a mostly static directory of HTML, CSS, and JavaScript. Internally, One runs a few different Vite production builds to output client, server, and API folders. This output is always in the dist directory.
Ensure your .env file has a ONE_SERVER_URL set to your production URL, like:
ONE_SERVER_URL=https://onestack.devAfter a successful web build, one build --step generate reuses the existing client assets, Vite manifest, and buildInfo.json while rebuilding the server and generating pages. Keep these outputs together. Run a full build first, and run it again when client code or routes change.
We provide a production server based on Hono with one serve that handles loaders, SSR, and API routes for you. You can choose a deploy target for that server. This can be chosen via your Vite configuration:
import { one } from 'one/vite'
export default { plugins: [ one({ web: { deploy: 'vercel' // defaults to 'node' } }) ]}For detailed deployment instructions, see the Deployment Guide.
If you are only using SPA and SSG routes and aren’t using loaders, you can statically serve the results of dist/client using any server you’d like.
By default, One uses worker threads to build static pages in parallel across multiple CPU cores. This can significantly speed up builds for sites with many pages.
One uses two workers by default, which keeps peak memory low. Set build.concurrency to use more when the machine has memory to spare:
import { one } from 'one/vite'
export default { plugins: [ one({ build: { concurrency: 4 } }) ]}ONE_BUILD_CONCURRENCY overrides the config value for one-off builds:
ONE_BUILD_CONCURRENCY=2 npx one buildYou can also disable worker threads entirely through config or an environment variable:
one({ build: { workers: false }})ONE_BUILD_WORKERS=0 npx one buildOne automatically scans your client bundles for leaked secrets after building. By default it logs warnings — for production deployments, we recommend setting securityScan to 'error' to fail the build if secrets are found:
import { one } from 'one/vite'
export default { plugins: [ one({ build: { securityScan: 'error' } }) ]}The scanner detects common API key patterns (Anthropic, OpenAI, Stripe, GitHub, AWS), bearer tokens, and generic secret assignments. See Configuration: build.securityScan for all options.
Build the native JS bundle with --platform ios or --platform android. This always runs through the Rolldown path, regardless of your native.bundler dev setting.
To ship to devices, integrate the bundle into the existing native build process. See Build or Run iOS for archiving and uploading.
Or check out the iOS Native Guide for instructions on building your iOS app with Xcode.
Edit this page on GitHub.