Turn Protocol Buffer source text into form-friendly metadata, service input/output hints and safe JSON examples.
proto-form-kit is meant for admin tools, API explorers, docs generators and internal dashboards that need to inspect a .proto file in the browser or in Node without generating a gRPC client.
- TypeScript types are generated from the source.
- ESM-only package marked as side-effect free for bundlers.
- CI runs
npm ci,typecheck,build, andtest. - Tested on Node.js 20 and 22 with GitHub Actions.
npm install proto-form-kitimport {
createProtoMethodExample,
createProtoExample,
getMethodFormSchema,
parseProtoFormSchema
} from 'proto-form-kit';
const schema = parseProtoFormSchema(`
syntax = "proto3";
package demo.inventory;
message ListProductsRequest {
string query = 1;
repeated string tags = 2;
map<string, int32> limits_by_region = 3;
}
message ListProductsResponse {
repeated Product products = 1;
}
message Product {
string id = 1;
Status status = 2;
}
enum Status {
STATUS_UNKNOWN = 0;
STATUS_ACTIVE = 1;
}
service ProductCatalog {
rpc ListProducts(ListProductsRequest) returns (ListProductsResponse);
}
`);
const method = getMethodFormSchema(schema, 'ProductCatalog', 'ListProducts');
const example = createProtoExample(schema, 'ListProductsRequest');
const methodExample = createProtoMethodExample(schema, 'ProductCatalog', 'ListProducts');
console.log(method?.input?.fields);
console.log(example);
// {
// query: '',
// tags: [''],
// limitsByRegion: { key: 0 }
// }
console.log(methodExample?.input);
console.log(methodExample?.output);Parses .proto source text and returns a serializable schema object:
const schema = parseProtoFormSchema(protoText, {
keepCase: true,
alternateCommentMode: true
});The returned schema contains:
packageNameimportsandweakImports- flattened
messages - flattened
enums - flattened
services diagnostics
By default keepCase is true, so field names preserve the .proto source name while each field also receives a jsonName helper in lower camel case.
Finds a message by short name or fully qualified name.
const message = getMessageFormSchema(schema, 'demo.inventory.ListProductsRequest');Finds a service method and resolves its input/output message schemas when available.
const method = getMethodFormSchema(schema, 'ProductCatalog', 'ListProducts');
console.log(method?.input?.fields);
console.log(method?.output?.fields);The result includes method streaming metadata:
method?.method.clientStreaming;
method?.method.serverStreaming;Builds JSON-friendly input and output examples for a service method.
const examples = createProtoMethodExample(schema, 'ProductCatalog', 'ListProducts');
console.log(examples?.input);
console.log(examples?.output);
console.log(examples?.diagnostics);This is the quickest helper when you are building a small API explorer or documentation page from a service definition.
Builds a JSON-friendly example object from a message schema.
const example = createProtoExample(schema, 'ListProductsRequest', {
maxDepth: 3,
includeOneof: true
});Example generation rules:
- scalar numbers become
0 int64,uint64and other long integer fields become'0', matching protobuf JSON string encoding- strings and bytes become
'' - booleans become
false - enums use the first declared enum value name
- repeated fields become one-item arrays
- maps become one-entry objects
- recursive messages stop at
maxDepth - oneof groups include the first field by default, or no field when
includeOneof: false
Each field includes a neutral control hint so UI code does not have to reverse-engineer protobuf types every time:
const product = schema.messages.find((message) => message.name === 'Product');
for (const field of product?.fields ?? []) {
console.log(field.name, field.control);
}Control values are:
textfor stringsnumberfor numeric scalar fieldscheckboxfor booleansbytesfor bytesselectfor enum fieldsfieldsetfor message fieldslistfor repeated fieldsmapfor map fieldsunknownfor unresolved types
Enum fields also expose enumValues directly:
const statusField = product?.fields.find((field) => field.name === 'status');
console.log(statusField?.enumValues);
// [
// { name: 'STATUS_UNKNOWN', value: 0 },
// { name: 'STATUS_ACTIVE', value: 1 }
// ]proto-form-kit supports the reflection features usually needed to generate forms or API examples:
- messages and nested messages
- enums and nested enums
- services and unary or streaming methods
- scalar, enum and message fields
- repeated fields
- map fields
- oneof groups
- comments when
alternateCommentModeis enabled - diagnostics for parse errors, unresolved imports and unresolved field types
The library parses source text only. It does not fetch files and it does not call Root.load, which keeps it browser-friendly and predictable.
If a schema declares imports, the import names are returned and a warning diagnostic is added:
const schema = parseProtoFormSchema(`
syntax = "proto3";
import "google/protobuf/timestamp.proto";
message Event {
google.protobuf.Timestamp created_at = 1;
}
`);
console.log(schema.imports);
console.log(schema.diagnostics);If you need imported types to resolve, concatenate or preprocess the relevant .proto sources before calling parseProtoFormSchema.
This package is not a protobuf encoder, decoder, validator or gRPC client generator. It is a small metadata layer for tooling UI, documentation and examples.
Use protobufjs, buf, protoc, connect-es or generated clients when you need runtime protobuf messages or RPC calls.
MPL-2.0