Supercharging Monorepo Workflows: Building Publishable Packages with Turborepo, Vite, and Changesets

Vinayak Hegde
3 min readAug 27, 2024

--

In multi-team environments, maintaining multiple packages in a monorepo can be challenging. A well-structured monorepo setup can improve efficiency, but it requires the right tools and practices to manage package building, dependency management, and publishing workflows effectively. Tools like Turborepo, alongside Vite and Changesets, will supercharge our workflow and developer experience (DevEx) to create publishable packages.

Why Vite?

Vite is a powerful, fast, and flexible tool that addresses many of the challenges faced in modern frontend development, especially in the context of monorepos and complex project setups. Its speed, ease of use, and robust feature set make it an ideal choice for developers looking to streamline their workflow and improve productivity. Whether you’re working on a small project or managing a large monorepo, Vite provides the tools you need to build performant, maintainable applications with minimal overhead.

Advantages of Vite:

  • Seamless integration with pnpm/Yarn Workspaces
  • Optimised builds of linked dependencies
  • Supports incremental builds in large projects
  • Optimised output using Rollup
  • Automatic code splitting for improved performance
  • Sensible defaults with minimal setup
  • Customisable configuration for complex setups

Why Changesets?

Changesets is a tool that helps manage versioning and changelogs for packages. It integrates seamlessly with monorepos, enabling you to automate the process of versioning and publishing packages based on changes in the code.

Key Benefits:

  • Automates versioning and changelogs
  • Streamlines publishing workflows
  • Works well with monorepos

Together, these tools (Turborepo + Vite + Changesets) provide a powerful setup for maintaining, building, and publishing multiple packages efficiently.

Prebuilding Linked Dependencies

Prebuilding dependencies, especially linked dependencies, is a crucial step in optimising monorepos for performance, particularly when working with tools like Vite and Turborepo. When you have packages that depend on one another within the same monorepo, handling these internal dependencies effectively can significantly impact development and build times.

Handling Dependencies (Understanding Linked Dependencies)

In a monorepo, packages often depend on each other. These are known as “linked dependencies” because, during development, they are typically linked together using tools like pnpm Workspaces. Linked dependencies can be a challenge when building for production because they aren’t treated the same way as external dependencies.

Scenario 1: Dependency Listed in package.json

When a dependency is listed in the package.json, whether it’s an external package (like react) or an internal one (like another package in the monorepo), Vite and Turborepo will handle it based on how you configure the build.

How to Prebuild These Dependencies:

  • List the Dependency in package.json:
    Ensure that the linked dependency is listed in the dependencies or devDependencies section of the consuming packages.
    { "dependencies": { "@my-org/shared-utils": "^0.0.1" } }
  • Prebuild the Dependency in Vite:
    Use the Optimisedeps.include option in the vite.config.ts to prebuild the dependency:
import { defineConfig } from 'vite';
export default defineConfig({
Optimisedeps: {
include: ['@my-org/shared-utils', 'react', 'react-dom'],
},
build: {
commonjsOptions: {
include: ['@my-org/shared-utils', /node_modules/],
},
},
});

This configuration ensures that @my-org/shared-utils and other specified packages are prebuilt when you start the dev server, speeding up hot reloads and improving build times.

Turborepo and Linked Dependencies:

Turborepo caches build outputs, so when you change a linked dependency (e.g., @my-org/shared-utils), only the affected packages are rebuilt. Pre-building these dependencies with Vite during development avoids redundant work.

Scenario 2: Dependency Not Listed in package.json

When you use a dependency in the code that isn’t listed in package.json, linked dependencies are treated as source code. During the build process, these dependencies are bundled directly into the package.

Takeaways:

  • Turborepo: Speeds up builds in monorepos by caching and optimizing the build process.
  • Changesets: Simplifies versioning and publishing packages.
  • Vite: Offers a fast, modern way to build packages with excellent support for dependency management.
  • Dependency Management: Always be mindful of what to add as a dependency to publishable packages.
  • Pre-build for Production: Prebundle common dependencies with Vite for faster builds.

--

--

Vinayak Hegde

Dad, Husband, Son, Brother, Coder (mostly JavaScript and python), micro-blogger