Skip to main content

AI does help me write code, but when I'm writing for you here, I only write my own words, not even using autofill. I would rather lose some time than lose your trust. - Scott

v1.5 - Workspace Tags, Dependency Rules, TypeScript Config Files, An MCP Server

· 4 min read
Scott
Lead Developer: bun-workspaces

bun-workspaces 1.5 is here! Let's cover some noteworthy feature additions since version 1's release.

Jump to: TypeScript Configs | Workspace Tags | Dependency Rules | MCP Server

TypeScript/JavaScript Config Files

bun-workspaces's optional config files were only able to be written in JSON/JSONC previously.

Now, config files can be written in TypeScript or JavaScript, such as in bw.workspace.ts:

import { defineWorkspaceConfig } from "bun-workspaces/config";

export default defineWorkspaceConfig({
  alias: "my-web-app",
  tags: ["frontend"],
  rules: {
    workspaceDependencies: {
      denyPatterns: [
        "tag:backend", 
        "path:packages/internal/**/*",
        "some-specific-workspace",
        "not:name:my-negated-name-pattern-*"
      ]
    }
  }
});

What makes this powerful beyond having TypeScript autofill for config properties is the ability to share code between config files via import/export, so you can more easily set up similar config files between workspaces, using whatever pattern you want in TypeScript.

The above config has some of the newest features showcased. Read on to learn more about them.

Workspace Tags

This is a simple concept but potentially very powerful for a project.

Prior, workspaces had several identifying traits: their name (from their respective package.json), any aliases configured in their bun-workspaces workspace configuration, and their path. It has been possible to match workspaces by any of these traits via workspace patterns.

Workspace tags are simply strings that can be added to a workspace's configuration that can be shared between workspaces.

Where these really come in handy is workspace patterns, which can be used when listing scripts and running scripts.

For example, workspace patterns could be workspace-name, path:my-glob/**/*, or now tag:my-tag/tag:my-tag-pattern-*, the latter matching all workspaces matching the given tag or tag wildcard pattern. In the CLI, bw run lint tag:my-tag will run the lint script from package.json for all workspaces that have "my-tag" in their configured tags.

These can be a useful pattern to use in workspace dependency rules, a new feature, covered next:

Workspace Dependency Rules

Monorepos are powerful for code sharing. The bun-workspaces documentation covers some of the basics behind workspace dependencies, which are declared in package.json dependencies like "my-workspace-name": "workspace:*".

Oftentimes, one of the main reservations people have about making code sharing simpler is leaking code that shouldn't be exposed in the wrong package.

Monorepos are great for developing a full stack application using TypeScript for both the frontend and backend, but people don't want their backend code being included in their frontend, especially for a web app where it's very easy to inspect and get code that was accidentally bundled.

Dependency rules let you use workspace patterns in your workspace configuration in order to allow or deny dependencies, so that bun-workspaces will exit with an error if any workspaces violate their rules.

For example, you could use the new tags to tag all your backend workspaces, so that your frontend workspaces can then deny backend code.

This does take into account the whole dependency tree, such as when a workspace that violates a rule is a dependency of a dependency.

With the new TypeScript configs as we have seen earlier, we could set up something like this for frontend workspaces:

// configHelpers.ts

import { type WorkspaceConfig } from "bun-workspaces/config";
  
export const FRONTEND_WORKSPACE_CONFIG: WorkspaceConfig = {
  tags: ["frontend"],
  rules: {
    workspaceDependencies: {
      denyPatterns: ["tag:backend"]
    }
  }
};

export const BACKEND_WORKSPACE_CONFIG: WorkspaceConfig = {
  tags: ["backend"]
};
// packages/my-frontend/bw.workspace.ts

import { defineWorkspaceConfig } from "bun-workspaces/config";
import { FRONTEND_WORKSPACE_CONFIG } from "../../configHelpers";

export default defineWorkspaceConfig({
  alias: ["my-fe"],
  ...FRONTEND_WORKSPACE_CONFIG
});
// packages/my-backend/bw.workspace.ts

import { defineWorkspaceConfig } from "bun-workspaces/config";
import { BACKEND_WORKSPACE_CONFIG } from "../../configHelpers";

export default defineWorkspaceConfig({
  alias: ["my-be"],
  ...BACKEND_WORKSPACE_CONFIG
});

Now you can reuse the configHelpers.ts utilities in any frontend-related or backend-related workspace, and if a frontend workspace declares a backend workspace as a dependency (or any workspace with a backend dependency itself, etc.), you will get an error.

MCP Server

See the Documentation for information about setup.

bun-workspaces is a newer, growing open source tool. That means that AI doesn't generally know about it by default. This is an issue with new open source, but that doesn't mean modern development is now stuck with only pre-existing open source tooling.

Now the CLI ships with an mcp-server command that you can use to set up in your tooling that supports MCP, like Cursor or Claude Code.

The server provides instructions outlining the overall use of the bun-workspaces CLI and TypeScript API to your AI, and it includes tools for using some of its functionality to get project metadata and resources that allow it to read more complete docs about all of its features if necessary.

Now your tooling doesn't have to guess how bun-workspaces works!