Protocol Buffers for JavaScript with TypeScript support, providing pure JavaScript implementation for serializing and deserializing structured data using Google's Protocol Buffer format.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Command-line utilities for static code generation, TypeScript definition generation, and protobuf schema compilation with multiple output formats and optimization options.
Main command-line tool for converting .proto files to JavaScript code with various output formats and optimization options.
# Basic usage
pbjs [options] file1.proto file2.proto ...
# Common options
pbjs -t static-module -w commonjs -o output.js input.proto
pbjs -t json -o schema.json input.proto
pbjs -t static -w es6 -o output.mjs input.protoCore Options:
# Target formats (-t, --target)
-t static-module # Static module with embedded types
-t static # Static code generation
-t json # JSON descriptor
-t json-module # JSON descriptor as module
# Wrapper formats (-w, --wrap)
-w commonjs # CommonJS module.exports
-w amd # AMD define()
-w es6 # ES6 export
-w closure # Google Closure
-w default # Default wrapper
# Output options
-o, --out # Output file path
-r, --root # Root directory for imports
-p, --path # Additional include pathsUsage Examples:
# Generate CommonJS static module
pbjs -t static-module -w commonjs -o messages.js messages.proto
# Generate ES6 module
pbjs -t static-module -w es6 -o messages.mjs messages.proto
# Generate JSON schema
pbjs -t json -o schema.json messages.proto
# Multiple input files
pbjs -t static-module -w commonjs -o bundle.js user.proto order.proto
# With include paths
pbjs -t static-module -w commonjs -p ./protos -p ./common -o output.js main.proto
# Minified output
pbjs -t static-module -w commonjs --no-comments --no-delimited -o min.js input.protoTypeScript definition generator that creates .d.ts files from JavaScript protobuf modules.
# Basic usage
pbts [options] input.js
# Common usage
pbts -o definitions.d.ts generated.js
pbts --main -o index.d.ts generated.jsCore Options:
# Output options
-o, --out # Output .d.ts file path
-n, --name # Global type name for definitions
-m, --main # Generate main entry point definitions
# Generation options
--no-comments # Omit comments in output
--global # Generate global definitionsUsage Examples:
# Generate TypeScript definitions
pbts -o messages.d.ts messages.js
# Generate main entry point definitions
pbts --main -o index.d.ts generated.js
# Global type definitions
pbts --global -n MyProtobuf -o global.d.ts messages.js
# Multiple source files
pbts -o combined.d.ts file1.js file2.jsAdvanced options for customizing code generation behavior and output format.
# pbjs advanced options
--keep-case # Keep original field case instead of camelCase
--alt-comment # Use alternate comment parsing
--no-create # Don't generate create() methods
--no-encode # Don't generate encode() methods
--no-decode # Don't generate decode() methods
--no-verify # Don't generate verify() methods
--no-convert # Don't generate convert methods
--no-delimited # Don't generate delimited methods
--no-beautify # Don't beautify generated code
--no-comments # Omit comments from output
--force-long # Force using Long for int64 fields
--force-number # Force using number for int64 fields
--force-message # Force message constructor styleUsage Examples:
# Minimal generation (smallest output)
pbjs -t static-module -w commonjs --no-comments --no-beautify \
--no-delimited --no-verify -o minimal.js input.proto
# Performance optimized
pbjs -t static-module -w commonjs --force-number \
--no-create --no-convert -o fast.js input.proto
# Keep original proto field names
pbjs -t static-module -w commonjs --keep-case -o original.js input.proto
# Alternative comment parsing for complex protos
pbjs -t static-module -w commonjs --alt-comment -o parsed.js input.protoDifferent output formats for various use cases and environments.
# Static module generation
pbjs -t static-module -w commonjs -o static.js input.proto
# JSON descriptor export
pbjs -t json -o descriptor.json input.proto
# JSON module export
pbjs -t json-module -w commonjs -o descriptor.js input.proto
# Static code generation (separate files)
pbjs -t static -w commonjs -o output/ input.protoTarget Format Examples:
# Static module (recommended for most use cases)
pbjs -t static-module -w commonjs messages.proto
# Output: Single file with embedded message constructors
# JSON descriptor (for dynamic loading)
pbjs -t json messages.proto
# Output: JSON representation of proto schema
# Static generation (separate files)
pbjs -t static messages.proto
# Output: Multiple files, one per message typeExamples of integrating protobuf compilation into various build systems.
# npm scripts in package.json
{
"scripts": {
"build:proto": "pbjs -t static-module -w commonjs -o src/proto.js proto/*.proto",
"build:types": "pbts -o src/proto.d.ts src/proto.js",
"build": "npm run build:proto && npm run build:types"
}
}
# Makefile integration
proto:
pbjs -t static-module -w commonjs -o src/messages.js proto/*.proto
pbts -o src/messages.d.ts src/messages.js
# Webpack integration (webpack.config.js)
module.exports = {
module: {
rules: [
{
test: /\.proto$/,
use: [
{
loader: 'protobuf-loader',
options: {
target: 'static-module',
wrap: 'commonjs'
}
}
]
}
]
}
};Examples of generated code for different target formats.
Static Module Output:
// Generated by pbjs -t static-module -w commonjs
"use strict";
var $protobuf = require("protobufjs/minimal");
var $root = ($protobuf.roots.default || ($protobuf.roots.default = new $protobuf.Root()));
$root.User = (function() {
function User(properties) {
if (properties)
for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
if (properties[keys[i]] != null)
this[keys[i]] = properties[keys[i]];
}
User.prototype.id = 0;
User.prototype.name = "";
User.create = function create(properties) {
return new User(properties);
};
User.encode = function encode(message, writer) {
if (!writer) writer = $Writer.create();
if (message.id != null && message.hasOwnProperty("id"))
writer.uint32(8).uint32(message.id);
if (message.name != null && message.hasOwnProperty("name"))
writer.uint32(18).string(message.name);
return writer;
};
// ... decode, verify, etc.
return User;
})();
module.exports = $root;JSON Descriptor Output:
{
"nested": {
"User": {
"fields": {
"id": {
"type": "uint32",
"id": 1
},
"name": {
"type": "string",
"id": 2
}
}
}
}
}TypeScript Definitions Output:
// Generated by pbts
import * as $protobuf from "protobufjs";
export interface IUser {
id?: (number|null);
name?: (string|null);
}
export class User implements IUser {
constructor(properties?: IUser);
public id: number;
public name: string;
public static create(properties?: IUser): User;
public static encode(message: IUser, writer?: $protobuf.Writer): $protobuf.Writer;
public static encodeDelimited(message: IUser, writer?: $protobuf.Writer): $protobuf.Writer;
public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): User;
public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): User;
public static verify(message: { [k: string]: any }): (string|null);
public static fromObject(object: { [k: string]: any }): User;
public static toObject(message: User, options?: $protobuf.IConversionOptions): { [k: string]: any };
public toJSON(): { [k: string]: any };
public static getTypeUrl(typeUrlPrefix?: string): string;
}Optimization strategies and options for generated code performance.
# Size optimization
pbjs -t static-module -w commonjs --no-comments --no-beautify \
--no-delimited --no-convert -o optimized.js input.proto
# Speed optimization
pbjs -t static-module -w commonjs --force-number \
--no-verify --no-create -o fast.js input.proto
# Memory optimization
pbjs -t static-module -w commonjs --force-message \
--no-convert -o memory.js input.protoOptimization Trade-offs:
# Smaller bundle size (removes optional methods)
--no-create # -15% size, lose convenience methods
--no-verify # -20% size, lose validation
--no-convert # -25% size, lose object conversion
--no-delimited # -5% size, lose delimited encoding
# Faster execution (use primitives over objects)
--force-number # +30% speed for int64, lose precision safety
--force-message # +15% speed, consistent object usage
# Better compatibility
--keep-case # Preserve proto field names
--force-long # Ensure int64 precisionCommon issues and debugging techniques for CLI tools.
# Verbose output for debugging
pbjs -t static-module -w commonjs --verbose -o debug.js input.proto
# Dependency resolution issues
pbjs -t static-module -w commonjs -p ./protos -p ../common \
--verbose -o output.js main.proto
# Import path debugging
pbjs -t static-module -w commonjs -r ./src/protos \
--verbose -o generated.js **/*.protoCommon Error Solutions:
# "Cannot resolve import" error
pbjs -p ./additional-path -p ./another-path input.proto
# "Duplicate definition" error
pbjs --alt-comment input.proto # Try alternate parsing
# "Invalid syntax" error
# Check proto file syntax with protoc first:
protoc --syntax_out=/dev/null input.proto
# TypeScript generation errors
pbts --verbose -o types.d.ts generated.jsAutomated workflows for protobuf compilation in CI/CD pipelines.
# GitHub Actions workflow
name: Build Protobuf
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16'
- run: npm install -g protobufjs-cli
- run: pbjs -t static-module -w commonjs -o src/proto.js proto/*.proto
- run: pbts -o src/proto.d.ts src/proto.js
# Docker build integration
FROM node:16-alpine
RUN npm install -g protobufjs-cli
COPY proto/ /app/proto/
WORKDIR /app
RUN pbjs -t static-module -w commonjs -o generated.js proto/*.proto
RUN pbts -o generated.d.ts generated.jsAutomated Build Scripts:
#!/bin/bash
# build-proto.sh
set -e
PROTO_DIR="./proto"
OUTPUT_DIR="./src/generated"
TEMP_JS="$OUTPUT_DIR/temp.js"
FINAL_JS="$OUTPUT_DIR/proto.js"
FINAL_TS="$OUTPUT_DIR/proto.d.ts"
mkdir -p "$OUTPUT_DIR"
echo "Generating JavaScript..."
pbjs -t static-module -w commonjs \
-o "$TEMP_JS" \
"$PROTO_DIR"/*.proto
echo "Generating TypeScript definitions..."
pbts -o "$FINAL_TS" "$TEMP_JS"
mv "$TEMP_JS" "$FINAL_JS"
echo "Generated:"
echo " $FINAL_JS"
echo " $FINAL_TS"
# Validate generated files
node -e "require('$FINAL_JS')" && echo "✓ JavaScript module loads correctly"# CLI exit codes
0 # Success
1 # General error
2 # Invalid arguments
3 # File not found
4 # Syntax error in proto
5 # Generation error
# File extensions
.proto # Protocol buffer definition files
.js # Generated JavaScript modules
.d.ts # Generated TypeScript definitions
.json # JSON descriptor files
.mjs # ES6 module filesInstall with Tessl CLI
npx tessl i tessl/npm-protobufjs