# Bedframe builds one extension for Chrome, Firefox and Edge from one project

> Bedframe is a Vite based framework for building, versioning and publishing cross-browser extensions, where the browser differences are expressed as per-browser manifest deltas rather than separate codebases, and a CLI covers scaffolding, dev, build, zip, version and publish. It suits a developer shipping an extension to several stores, and it is a young project with a 0.1.x CLI.

**nyaggah/bedframe** — Your Browser Extension Development Framework

- Repository: https://github.com/nyaggah/bedframe
- Website: https://bedframe.dev
- Stars: 582 · Forks: 8
- Language: TypeScript
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/nyaggah-bedframe

## The B.E.D. model, and what per-browser manifest deltas mean

Bedframe is described as a Vite-based framework for building, versioning and publishing cross-browser extensions from one project, and it is organised around what the README calls the B.E.D. model. Browser covers browser targets and per-browser manifest deltas. Extension covers extension type, pages, scripts and runtime surface. Development covers framework, language, tooling, testing and release flow. The middle term is the one that solves the actual problem. A browser extension manifest is a JSON file whose keys differ between Chrome and Firefox, and the usual approach is to keep one manifest and patch it, or to keep several. Bedframe makes the difference a first class part of the configuration, so you declare the deltas and the framework produces the right manifest per target. That is a much better answer than a build script that rewrites the manifest with string replacements, and it is the reason the project exists rather than the Vite part, since Vite alone would not give you a packaged, versioned extension in three stores.

## The CLI is the interface, and the commands are the workflow

The packages table describes @bedframe/cli as CLI workflows for scaffold, dev, build, zip, version and publish, and the getting started section shows the whole life of a project in a handful of commands. You install the CLI globally with your package manager of choice, and the README gives all four forms:

```bash
# pnpm
pnpm add -g @bedframe/cli

# npm
npm install -g @bedframe/cli

# yarn
yarn global add @bedframe/cli

# bun
bun add -g @bedframe/cli
```

Then you create a project with bedframe make, and run the standard flow with bedframe dev, bedframe build and bedframe zip. The release side is bedframe version and bedframe publish, and the publish command takes an explicit browser list, for example bedframe publish --browsers chrome,firefox,edge. That last detail is the one worth noting, because it says publishing is per target rather than all at once, which is what you want when one store's review takes a day and another's takes a week, or when you are not ready to submit to a particular store yet. The make command is the same entry point the create-bedframe package provides, and that package is listed separately as a standalone project-creation utility, which suggests the scaffolding can be used without the rest of the framework.

## A monorepo of three published packages and two shared ones

The repository is a pnpm workspace with packages/* and examples/*, driven by Turbo, and the published surface is small. @bedframe/cli is the command line tool. @bedframe/core holds the core Bedframe APIs, Vite integration helpers and shared types, which is where the framework proper lives. @bedframe/skills is described as portable agent-ready Bedframe guidance, an AGENTS.md plus skills references, which is an unusual package and worth commenting on. It is a machine-readable description of how the framework wants to be used, packaged so it can be installed into another repository. Then create-bedframe is the standalone project-creation utility, and the two monorepo utility packages are eslint-config-bedframe for shared lint configuration and @bedframe/tsconfig for shared TypeScript configuration. The root package is private and named @bedframe/monorepo at version 0.0.0, with a scripts set that wraps every task in turbo run and disables Turbo telemetry before the build and release tasks, a detail that shows the maintainer cares about what the build reports.

## The examples show which extension surfaces are supported

The examples directory is the fastest way to see what the framework actually supports, and it lists six projects. There is devtools-react-ts, which is a developer tools panel, overlay-react-ts, which is a content overlay drawn into a page, popup-react-ts and popup-svelte-ts, which are the same surface in two different frameworks, and sidepanel-react-ts, which is the side panel surface. Two things follow from that list. The React and Svelte variants of the popup exist because the framework is meant to sit under whatever UI library you prefer rather than imposing one, which is consistent with it being a Vite integration rather than a framework with components. And the four distinct surfaces covered here are the ones a browser extension actually has, so the framework's abstraction is the extension type rather than the UI. The example names also encode the language choice, with the ts suffix throughout, and the topic list on the repository is components, eslint, nextjs, react, svelte, typescript, vite and vue, so the surrounding ecosystem of the projects using it is broad.

## Release tooling, hooks and the agent contract

The release script in the root manifest is a full quality gate. It runs turbo telemetry disable and then format, lint and build, then changeset version and changeset publish, and the prerelease script stops after the format, lint and build. The workspace uses Changesets with a .changeset/ directory at the root, and the release history shows that pattern working, with @bedframe/cli at 0.1.2 published on 2026-03-17 and create-bedframe at 0.1.1 and 0.1.0 both on 2026-03-10. Commits go through commitlint with the conventional config, and commitizen is wired in so that the cz command opens the conventional prompt, with the cz-conventional-changelog adapter. Git hooks are handled by lefthook, installed through the prepare script with a trailing or true so a failure to install does not break install, and lint-staged is present for staged files. The AGENTS.md plus the @bedframe/skills package is the piece with no equivalent in most frameworks, and it is the one to look at if you plan to work on Bedframe with an AI assistant, because it is a portable contract rather than something you have to rediscover from the source.

## Conclusion

Adopt Bedframe when you maintain one browser extension and need to ship it to Chrome, Firefox and Edge from a single codebase without maintaining three manifest files by hand. Do not adopt it as a general web framework, since everything it does is oriented at extension packaging, versioning and store publishing. Verify first which of the extension surfaces your project needs, since the examples cover a devtools panel, an overlay, a popup, a side panel and a content script, and that the browsers you target are supported by the version of the CLI you install, since the publish command takes an explicit browser list.

## FAQ

### What is Bedframe and what problem does it solve?

It is a Vite based framework for building, versioning and publishing cross-browser extensions from one project, organised around the B.E.D. model of browser targets and per-browser manifest deltas, extension type and pages and scripts and runtime surface, and the framework and language and tooling and testing and release flow.

### How do I install the Bedframe CLI and create a project?

Install it globally with pnpm add -g @bedframe/cli, npm install -g @bedframe/cli, yarn global add @bedframe/cli or bun add -g @bedframe/cli, then run bedframe make to create a project. The standard flow afterwards is bedframe dev, bedframe build and bedframe zip.

### How do I publish a Bedframe extension to several browsers?

Run bedframe version and then bedframe publish with an explicit browser list, for example bedframe publish --browsers chrome,firefox,edge. The command is per target rather than all at once, so you can submit to one store without the others.

### Which packages make up the Bedframe framework?

Three published packages, @bedframe/cli for scaffolding and the workflows, @bedframe/core for the core APIs, Vite integration helpers and shared types, and @bedframe/skills for portable agent-ready guidance. There is also create-bedframe as a standalone project-creation utility, and two shared utility packages, eslint-config-bedframe and @bedframe/tsconfig.

## Sources

- [License: MIT](https://github.com/nyaggah/bedframe/blob/main/LICENSE)
- [nyaggah/bedframe on GitHub](https://github.com/nyaggah/bedframe)
- [Project website](https://bedframe.dev)
- [README](https://github.com/nyaggah/bedframe/blob/main/README.md)
- [Releases](https://github.com/nyaggah/bedframe/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nyaggah-bedframe
