Skip to content

Well-known types

Protobuf ships with a standard library of types defined in google/protobuf/*.proto. Protobuf-ES provides them as precompiled exports from @bufbuild/protobuf/wkt, with convenience APIs for the ones that map naturally to JavaScript values.

If your schema imports a well-known type, generated code imports it from @bufbuild/protobuf/wkt automatically.

The well-known type package includes generated output for:

  • google/protobuf/any.proto
  • google/protobuf/api.proto
  • google/protobuf/compiler/plugin.proto
  • google/protobuf/cpp_features.proto
  • google/protobuf/descriptor.proto
  • google/protobuf/duration.proto
  • google/protobuf/empty.proto
  • google/protobuf/field_mask.proto
  • google/protobuf/go_features.proto
  • google/protobuf/java_features.proto
  • google/protobuf/source_context.proto
  • google/protobuf/struct.proto
  • google/protobuf/timestamp.proto
  • google/protobuf/type.proto
  • google/protobuf/wrappers.proto

Some of them also get convenience APIs.

Timestamp represents a point in time with nanosecond precision.

import {
type Timestamp,
timestampNow,
timestampFromDate,
timestampFromMs,
timestampDate,
timestampMs,
} from "@bufbuild/protobuf/wkt";
let ts: Timestamp = timestampNow();
ts = timestampFromDate(new Date(1938, 0, 10));
ts = timestampFromMs(818035920123);
const date: Date = timestampDate(ts);
const ms: number = timestampMs(ts);

Duration represents a fixed span of time with nanosecond precision.

import { type Duration, durationFromMs, durationMs } from "@bufbuild/protobuf/wkt";
const duration: Duration = durationFromMs(1012);
const ms: number = durationMs(duration);

Any stores an arbitrary message as binary data together with its type URL.

import { create, createRegistry } from "@bufbuild/protobuf";
import { type Any, anyPack, anyIs, anyUnpack } from "@bufbuild/protobuf/wkt";
import { type User, UserSchema } from "./gen/example_pb";
let user: User = create(UserSchema);
let any: Any = anyPack(UserSchema, user);
anyIs(any, UserSchema); // true
anyIs(any, "example.User"); // true
anyUnpack(any, UserSchema); // User | undefined
const registry = createRegistry(UserSchema);
anyUnpack(any, registry); // Message | undefined

Registries are especially useful when you do not know the target type up front. See Registries and Any with registries.

Struct represents dynamic JSON-like objects. When a field uses google.protobuf.Struct, Protobuf-ES generates it as JsonObject.

/**
* @generated from field: google.protobuf.Struct struct = 1;
*/
struct?: JsonObject | undefined;

That makes it easy to assign plain values directly:

myMessage.struct = {
text: "abc",
number: 123,
};

The wrappers in google/protobuf/wrappers.proto become unboxed optional primitives when used in fields.

/**
* @generated from field: google.protobuf.BoolValue bool_value_field = 1;
*/
boolValueField?: boolean | undefined;

Wrappers are useful when you need to distinguish absence from a primitive’s default value, or when you want to pack primitives into Any.

descriptor.proto and compiler/plugin.proto are also included. Those types are the foundation for reflection, custom options, and plugin development.

See Reflection, Writing plugins, and Custom option redaction.