We made improvements to remote code generation features of the BSR. This page has been replaced with a new BSR NPM registry section.
For existing users, please see the Migrating from alpha guide and if you run into issues contact us on Buf Public Slack.
The Buf Schema Registry (BSR) supports
remote code generation for [JavaScript] and [TypeScript]. With
this feature, you can push [Buf modules][modules] to the BSR and install code
stubs generated from those modules using dependency management tools like [npm]
and [Yarn]. JavaScript and TypeScript source code generated by the BSR is hosted
on the BSR's [npm registry][npm-registry] at npm.buf.build
.
With this feature, you no longer need to maintain Protobuf files or runtime dependencies like [protoc] plugins—in fact, JavaScript and TypeScript developers can avoid local code generation altogether for any Buf modules that have been pushed to the BSR.
Setup
npm is configured to use the public npm registry at [registry.npmjs.org][npm-registry] by default. To configure npm to use Buf's npm registry at [npm.buf.build][buf-npm] in addition to the default registry, use this command to [set][npm-config] your npm config:
$ npm config set @buf:registry https://npm.buf.build
This binds the @buf
package scope to the BSR and updates your global
[.npmrc
][npmrc] accordingly.
You can configure [Yarn] in an analogous way:
$ yarn config set @buf:registry https://npm.buf.build
Available templates
The table below lists the generation templates that are officially supported by the BSR:
Template | What it generates |
---|---|
[protocolbuffers/js ][pb-js] | JavaScript code stubs (.js ) |
[grpc/web ][grpc-web] | JavaScript code stubs (.js ), TypeScript type definitions (.d.ts ) |
In addition to these official templates, you can use any templates you like with
npm—including templates that
you upload yourself—provided that those templates
generate valid JavaScript and/or TypeScript declaration files. Templates that
generate invalid code aren't supported. This operation, for example, would fail
because the template, [protocolbuffers/go
][pb-go], isn't supported:
$ npm install @buf/protocolbuffers_go_acme_paymentapis
Outputnpm ERR! code EINVALIDPACKAGENAME npm ERR! Invalid package name "google.golang.org/protobuf" of package "google.golang.org/protobuf@v1.28.1": name can only contain URL-friendly characters.
Installing packages
With your npm config set, you can install @buf/*
packages in any standard npm project. Here's an example
installation command:
$ npm install @buf/protocolbuffers_js_acme_paymentapis
npm registry using npm install
can take longer than installing from the
standard npm registry. This happens because packages are generated "on the
fly"—that is, they're built upon request and then cached. The first
npm install
typically takes longer than subsequent requests. :::
Package names
The BSR NPM registry has a special syntax for package names:
In the first example, @buf/protocolbuffers_js_acme_petapis
, the BSR applies
the protocolbuffers/js
template to the acme/petapis
module and thus
generates JavaScript code stubs for the Protobuf definitions in that module.
This table shows some example template/module name combinations and the resulting package name:
Template | Buf module | Package name |
---|---|---|
grpc/web | acme/petapis | @buf/grpc_web_acme_petapis |
protocolbuffers/js | bufbuild/buf | @buf/protocolbuffers_js_bufbuild_buf |
protocolbuffers/js | acme/paymentapis | @buf/protocolbuffers_js_acme_paymentapis |
Package versions
By default, when you npm install
a Buf module, the BSR generates
code from the most recent
reference for the module. But
you can also install a specific package version using npm's standard @
syntax:
$ npm install @buf/protocolbuffers_js_acme_paymentapis@1.1.2
Package version syntax is based on the BSR's concept of synthetic versions:
With package versions:
- The major version is always 1.
- The minor version (3 in the first example) corresponds to the
template version (without the
v
prefix). Template versions increase monotonically and have the formv1
,v2
,v3
... - The patch version (5 in the first example) corresponds to the module, which is identified by a commit sequence ID that's incremented each time a new version of a module is pushed.
This command, for example, applies version 1 of the
protocolbuffers/js
template to a commit with an ID of 2 (the
second commit pushed to the module):
$ npm install @buf/protocolbuffers_js_acme_paymentapis@1.1.2
Using private packages
To install npm packages generated from private Buf modules, you need
to configure npm to send an authentication token with each request to the BSR
npm registry. Add a line with this syntax to your .npmrc
file:
You can use an existing auth token or generate a new one. To create a new one, log into the BSR, navigate to your user settings page, and click Create Token.
Other package managers
Because the Buf npm registry implements npm's public registry API, you should be able to use it with package management tools outside of npm, such as Yarn and pnpm, though with some known limitations.
Known limitations
The BSR NPM registry has a few limitations that you should be aware of.
Yarn compatibility
Yarn versions greater than v1.10.0 and less than v2 are
not supported. These versions of Yarn require the shasum
field in the dist
object to be set, but the BSR can't compute a digest without generating the code
for all possible versions of the package.
Runtime dependencies
If you're creating your own plugins, you can use labels
to declare runtime dependencies for plugins. The BSR NPM registry currently
supports semantic versioning for versions, like 0.1.0
or
1.2.3-SNAPSHOT
, but not semver ranges like >=1.2.7
or <1.3.0
.
Import rewrites
If the module you request has dependencies, the npm registry rewrites any relative import paths so that they point to the package with a full package name. Here's an example rewrite:
// generated import
require("../../google/storage/v1/storage_pb.js");
// replacement
require("@buf/grpc_web_googleapis_googleapis/google/storage/v1/storage_pb.js");
What this means in practice is that files generated by Protobuf plugins must
use the same path as their .proto
counterparts, although suffixes like _pb
and additional file extensions are allowed. The table below shows an original
Protobuf filepath (foo/bar.proto
) and which generated filepaths would be
acceptable (or not).
Proto filepath | Path of generated file | Acceptable? |
---|---|---|
foo/bar.proto | foo/bar.js | ✅ |
foo/bar.proto | foo/bar_pb.js | ✅ |
foo/bar.proto | foo/bar_pb.ts | ✅ |
foo/bar.proto | foo/bar_grpc.d.ts | ✅ |
foo/bar.proto | foo-bar.js | ❌ |
foo/bar.proto | some/other/path.ts | ❌ |
If you're a plugin author, be sure to heed this naming structure; otherwise, consumers of your APIs are likely to experience broken imports.