Vite
Purpose and Scope
Vite is documented as a first-class framework integration for Turborepo because it is a fast, lean build tool for modern web projects and a common choice for applications inside JavaScript and TypeScript workspaces. This page explains the repository-backed workflow for starting from an official example, adding a Vite app to an existing workspace, wiring that app to internal packages, and accounting for microfrontend or Module Federation needs. It is aimed at developers who already have, or are creating, a Turborepo monorepo and want Vite to participate cleanly in package-manager workspaces and task execution. Sources: apps/docs/content/docs/guides/frameworks/vite.mdx
The Vite guide belongs to the broader framework guide section, which explicitly presents Turborepo as working with any framework while still offering focused pages for common frontend stacks. That framing matters: Turborepo is not replacing Vite, and Vite is not a special scheduler inside Turborepo. Instead, Vite remains the application build and development tool, while Turborepo coordinates scripts, dependencies, caching, filtering, and package graph execution around it. The adjacent Next.js and Nuxt pages follow the same structure, which confirms that the Vite flow is part of a shared framework integration pattern rather than a one-off recipe. Sources: apps/docs/content/docs/guides/frameworks/index.mdx, apps/docs/content/docs/guides/frameworks/meta.json, apps/docs/content/docs/guides/frameworks/nextjs.mdx, apps/docs/content/docs/guides/frameworks/nuxt.mdx
Relevant Source Files
- apps/docs/content/docs/guides/frameworks/vite.mdx — Primary Vite integration guide, including quickstart commands, existing-repository scaffolding, internal package dependency examples, task customization, microfrontend base configuration, and Module Federation example guidance.
- apps/docs/content/docs/guides/frameworks/framework-bindings.mdx — Explains how shared library packages can expose framework-specific bindings using peer dependencies and export paths, a pattern that can apply when Vite apps consume framework-aware libraries.
- apps/docs/content/docs/guides/frameworks/index.mdx — Defines the framework guide section and states the cross-framework premise that Turborepo works with any framework.
- apps/docs/content/docs/guides/frameworks/meta.json — Lists the framework guide ordering, including Vite and framework bindings, which helps locate related documentation.
- apps/docs/content/docs/guides/frameworks/nextjs.mdx — Provides a neighboring framework guide with the same integration shape: quickstart, adding an app, internal package dependency setup, task customization, and microfrontend path configuration.
- apps/docs/content/docs/guides/frameworks/nuxt.mdx — Provides another neighboring framework guide and mirrors the Vite-style microfrontend base setting for Vite-powered routing assets.
Quickstart with the Vite Example
The fastest supported path is to create a new Turborepo from the official Vite example. The guide names the example as with-vite and provides package-manager-specific launcher commands for pnpm, Yarn, npm, and Bun. This is the right starting point when a team wants to see a working workspace layout before making architectural decisions, because the example starts with Turborepo, workspace packages, and Vite already arranged to cooperate. It also reduces ambiguity around where application packages live and how root scripts delegate work to packages. Sources: apps/docs/content/docs/guides/frameworks/vite.mdx
Use the command variant that matches the package manager selected for the repository: pnpm dlx create-turbo@latest -e with-vite, yarn dlx create-turbo@latest -e with-vite, npx create-turbo@latest -e with-vite, or bunx create-turbo@latest -e with-vite. The important part is not only the launcher syntax but the example flag, because that tells the create flow to use the Vite starter rather than the default template. After creation, treat the generated repository as a normal Turborepo workspace: install dependencies if needed, inspect the root task configuration, and run the app scripts through the package manager or through Turborepo task orchestration.
Adding Vite to an Existing Workspace
For an existing monorepo, the guide recommends using the Vite project scaffolder from the repository root and placing the new application under a package path such as apps/my-app. The documented commands are pnpm create vite@latest apps/my-app, yarn create vite@latest apps/my-app, npm create vite@latest apps/my-app, and bun create vite@latest apps/my-app. Running the command from the root keeps the generated application inside the workspace shape, rather than creating an isolated project beside it. That location is important because Turborepo discovers and coordinates work through the package-manager workspace and the package scripts that live in each package. Sources: apps/docs/content/docs/guides/frameworks/vite.mdx
After scaffolding, the Vite app still needs to be integrated into the repository rather than treated as complete. The guide calls out two practical follow-up steps: run the package manager install command, and update package scripts when the generated defaults do not match the repository’s task names. In practice, that means checking that the app exposes the scripts your root task configuration expects, such as build, dev, lint, or test if those tasks are part of the workspace. Turborepo can only schedule scripts that exist in packages, so this small package-level cleanup is what connects the Vite generator output to the monorepo task graph.
Internal Packages and Shared UI
A Vite application commonly depends on internal packages such as a shared design system, utility library, or TypeScript configuration package. The guide shows adding @repo/ui to the app dependency list, with workspace protocol differences by package manager. pnpm and Bun use workspace:*, while Yarn and npm examples use *. The exact version string is package-manager-specific, but the intent is the same: the app should resolve the library from the local workspace rather than from the public registry. This lets the Vite app consume shared code and allows Turborepo to understand the package relationship when tasks depend on upstream packages. Sources: apps/docs/content/docs/guides/frameworks/vite.mdx
When shared libraries need framework-aware behavior, use the framework binding pattern documented next to the Vite guide. The framework bindings page explains that a library can declare a framework or dependency as a peer dependency so the consuming application supplies the concrete version. It also recommends splitting framework-specific exports into separate entry points so bundlers can understand the intended target more clearly. Although the example uses Next.js, the page explicitly says the concept applies to any framework or dependency. For Vite repositories, this is useful when a shared package exposes React, Vue, Svelte, Solid, Preact, or other framework-specific bindings consumed by different Vite apps. Sources: apps/docs/content/docs/guides/frameworks/framework-bindings.mdx
Task Configuration and Package Overrides
By default, a newly added Vite application uses the tasks defined in the root turbo.json. That means the application participates in the same workspace-level task policy as the rest of the repository unless you intentionally override it. This default is convenient when all apps share common build, dev, and validation behavior, but it can be too broad when a Vite app has unique outputs, long-running development behavior, or different script names. The Vite guide points readers to package configurations for app-specific task customization, which is the correct mechanism when one package needs behavior that diverges from the root configuration. Sources: apps/docs/content/docs/guides/frameworks/vite.mdx
A useful mental model is that Vite owns the implementation of the app command, while Turborepo owns how that command is selected, ordered, cached, and composed with other packages. If a root task says to build packages, the Vite app should expose a compatible build script. If a package-specific configuration changes outputs or dependencies, it should describe the Vite app’s actual artifacts and relationships. This separation keeps framework configuration in the app and orchestration policy in Turborepo, which makes the repository easier to reason about when multiple frameworks live side by side.
Microfrontends and Module Federation
The Vite guide includes a specific microfrontend warning: when using Vite with Turborepo microfrontends, set the Vite base property for child applications. The reason given is asset routing. Images, CSS, and other built assets need to be routed to the correct application when a child app is mounted under a path. The documented example sets base to /admin in vite.config.ts using Vite’s defineConfig. This is the Vite equivalent of the path configuration shown in neighboring framework guides, where Next.js uses basePath and Nuxt also uses a Vite-style base configuration. Sources: apps/docs/content/docs/guides/frameworks/vite.mdx, apps/docs/content/docs/guides/frameworks/nextjs.mdx, apps/docs/content/docs/guides/frameworks/nuxt.mdx
For runtime composition, the guide directs readers to the with-vite-module-federation example. That example is separate from the basic with-vite starter because Module Federation introduces a different integration concern: composing independently built applications at runtime rather than simply sharing packages at install time. The guide also notes that Module Federation works with many frameworks and libraries, including React, Vue, Svelte, Solid, and Preact. Choose this path when the boundary between Vite applications is intentionally runtime-oriented. If the goal is only shared code, internal workspace packages are usually the simpler starting point.
Practical Setup Checklist
- Start from
with-vitewhen creating a new repository and you want a known-good Vite Turborepo example. - Use the Vite scaffolder from the repository root when adding an app to an existing workspace.
- Place the generated app under a workspace package path such as
apps/my-app. - Add internal packages such as
@repo/uito the app dependencies using the version protocol expected by your package manager. - Run the package manager install command after editing dependencies or adding the generated app.
- Align package scripts with the task names used by the root Turborepo configuration.
- Use package configurations when the Vite app needs task behavior that differs from the root defaults.
- Set Vite
basefor child microfrontend apps so static assets resolve beneath the correct route. - Use the
with-vite-module-federationexample when the project needs runtime composition instead of only workspace package sharing.
Next Steps
After the Vite app is running, read the package configuration reference before changing app-specific task behavior, then review the internal packages guide if shared code is central to the workspace design. For UI libraries that need framework-specific entry points, continue to framework bindings. For route-mounted or independently composed applications, continue to the microfrontends guide and compare the basic Vite example with the Vite Module Federation example. Those pages help decide whether a shared package, a path-mounted child app, or runtime composition is the correct boundary for the system you are building.