An annotation is a typed value attached to a schema, a field, or an object. Annotations on a type are saved with the
type’s schema, so they replicate with it and a tool that has never seen the code can still read them.
Returns a Type.Type entity — a live, in-memory TypeSchema instance,
NOT a Schema.Schema. Use Type.InstanceType<typeof Foo> for the instance
type and Type.getSchema(Foo) to obtain the underlying Effect Schema.
The entity's id defaults to EntityId.deterministic(typename, version) so
constructing a type never reaches crypto.getRandomValues() — required for
Cloudflare workerd, which forbids RNG calls in global (module-evaluation)
scope. Pass { id } to override (e.g. with EntityId.random() from a
request handler).
Giving the type a nominal class name keeps its inferred type portable for
declaration emit: structural expansion (which can pull in unnameable union
members from referenced schemas) is replaced by a reference to the class.
The second call takes either a schema, or struct fields (wrapped in Schema.Struct) with an optional function
that pipes annotations onto the struct.
Defines a struct schema from a map of field schemas.
Details
Each field value is a schema. Use
optionalKey
or
optional
to
mark fields as optional, and
mutableKey
to mark them as mutable.
The resulting schema's Type is a readonly object type with the fields'
decoded types. The Encoded form mirrors the field schemas' encoded types.
Declared fields may be inherited and are copied to own properties in the
output. The __proto__ field is accepted only when it is an own property.
Parsing does not guarantee that output keys retain their input order.
AnnotationHelper<string[]>.set: (value: string[]) => <SextendsSchema.Top>(schema: S) => S
Set the annotation on an Effect schema.
Only accepts Schema.Top — annotations must be applied to the
source schema BEFORE wrapping it with Type.makeObject / Type.makeRelation.
In a pipe, place every Annotation.X.set(...) before the Type.make... step.
Annotation<IconAnnotation>.set: (value: Annotation.IconAnnotation) => <SextendsSchema.Top>(schema: S) => S
Set the annotation on an Effect schema.
Only accepts Schema.Top — annotations must be applied to the
source schema BEFORE wrapping it with Type.makeObject / Type.makeRelation.
In a pipe, place every Annotation.X.set(...) before the Type.make... step.
@performance ― O(value size) encode, once at schema-definition time.
set({
13
icon: string
Sprite icon name (e.g., 'ph--user--regular', 'ph--cube--regular', 'px--anthropic--regular').
ph--* is Phosphor; px--* and dx--* are brand glyphs, which are sprite-only and carry no
weight variants. All three are admitted because a type whose subject IS a brand — an Anthropic
session, a GitHub repo — has no honest Phosphor equivalent.
AnnotationHelper<string>.set: (value: string) => <SextendsSchema.Top>(schema: S) => S
Set the annotation on an Effect schema.
Only accepts Schema.Top — annotations must be applied to the
source schema BEFORE wrapping it with Type.makeObject / Type.makeRelation.
In a pipe, place every Annotation.X.set(...) before the Type.make... step.
set('summary'),
17
),
18
) {}
19
Annotation
Value
What reads it
LabelAnnotation
The fields that label an object, in order
Obj.getLabel, lists and pickers
DescriptionAnnotation
The field that describes an object
Obj.getDescription
IconAnnotation
An icon and a hue
Composer’s navigation tree and cards
FormInputAnnotationFormLayoutAnnotation
Whether a field shows in a form, and the form’s layout
Only accepts Schema.Top — to read an annotation off a Type.Type
entity, unwrap it first with Type.getSchema(entity). This keeps the
annotation pipeline single-shaped and forces annotations to live on the
source schema, not on the post-construction Type entity.
@performance ― O(1) annotation lookup, but decodes the value against schema on every call (not cached).
For static Type.Obj / Type.Relation entities the source Effect Schema is
read from a hidden slot — these overloads preserve the instance type.
For Type.Type entities (the meta-schema kind) the schema is rebuilt from
type.jsonSchema; the instance type isn't statically knowable so the wide
AnyEntity overload widens to Schema.Codec<any, any>.
Always call this when you need to interact with the Effect Schema API
(e.g. before passing to Effect.Schema functions). For ECHO-side APIs
(Obj.make, Filter.type, Ref) pass the type entity directly.
Only accepts Type.AnyEntity — raw Schema.Schema values can be used
directly without unwrapping.
@performance ― O(1) cached read; a persisted type rebuilds its Effect Schema from jsonSchema (O(schema size)) on
first access.
Annotation.make defines an annotation with an id and a schema for its value. Set it on a schema like the built-in ones,
or on one object with Annotation.set, which stores the value in the object’s metadata.
Perform mutations on an echo object within a controlled context.
All mutations within the callback are batched and trigger a single notification
when the callback completes. Direct mutations outside of Obj.update will throw
an error for echo objects.
This function also works with nested objects within echo objects (e.g., Template structs)
that are reactive at runtime.
@param ― obj - The echo object to mutate. Use Relation.update for relations.
@param ― callback - The callback that performs mutations on the object.
@example
const person = Obj.make(Person, { name: 'John', age: 25 });