Email templates
Write an email template as one TSX file that Samva reads without running, so developers, agents, and the visual editor all edit the same source.
A template is one TSX file written in the static profile: ordinary JSX, HTML, and Tailwind classes that Samva reads without running. Compiling the file produces an IR, a JSON description of the email that holds the markup, the bindings to your input, the conditions, the loops, and the formatters. The visual editor, agents, previews, and every send render that IR, so nothing you write executes when a message goes out.
SML is the name of this toolkit: the TSX source in the static profile, the compiler that turns it
into IR, and the tools that read it. You will see it in the @samva/markup package, the sml agent
skill, and the /docs/sml URLs. A template you write is TSX; SML is not a second syntax to learn.
import { defineTemplate } from "@samva/markup";
import { Email, Section } from "@samva/markup/email";
import { jsonSchema } from "@samva/markup/input-schema";
export default defineTemplate({
id: "welcome",
schema: jsonSchema<{ firstName: string; plan?: string }>({
type: "object",
properties: { firstName: { type: "string" }, plan: { type: "string" } },
required: ["firstName"],
additionalProperties: false,
}),
fixtures: {
default: { firstName: "Ada", plan: "Pro" },
"no-plan": { firstName: "Ada" },
},
email: {
subject: (input) => `Welcome, ${input.firstName}`,
preheader: () => "Your account is ready",
body: (input) => (
<Email>
<Section className="px-8 py-6">
<h1 className="text-2xl font-semibold">Welcome, {input.firstName}</h1>
{input.plan && <p>You are on the {input.plan} plan.</p>}
</Section>
</Email>
),
},
});One file for developers and marketers
Developers and marketers work on the same .tsx file in the same Git repository, so a project moves
between them with no export or conversion.
| Developer with their own agent | Marketer with the hosted agent | |
|---|---|---|
| Starts from | samva templates init, which creates a project on Samva and clones it | A starter from the template gallery in the dashboard |
| Edits with | Claude Code, Cursor, or any editor | Chat with the hosted assistant, plus direct edits on the canvas |
| Sees | TSX and a local preview of every fixture | The rendered email for each fixture |
| Checks with | samva templates check, render, and snapshot | The same checks, shown as findings |
| Saves with | git commit and git push | Save version, a Git commit on the same branch |
| Ships with | samva templates publish, then typed sends from the SDK or CLI | Publish in the dashboard |
Every edit, whoever makes it, lands as a revision of the same file, and conflicts surface for explicit resolution.
Why a static profile
Compiling a template reads the file and reports problems without executing anything, so every surface gives the same answer:
- A binding to a field the input schema does not declare fails at compile time, with the nearest field name suggested.
- Every fixture is validated against the schema before you can save or publish.
- Sending renders the published IR against the payload you send. There is no code to run, so rendering is a pure function of the IR and the input.
The trade is that a body cannot compute. Logic the profile cannot express, such as a total or a sorted list, is computed by the caller and sent in the payload. There is no escape hatch.
Where to go next
Authoring in TSX
Project layout, the definition, the local editor, and publishing.
The static profile
Every form a body may use, and what it compiles to.
Template inputs
Schemas, fixtures, bindings, formatters, locale, and time zone.
Partials
Reusable components that compile into each template.
Diagnostics
Stable codes, locations, and fixes for every finding.
The agent loop
Write, check, render, look, and repair over the CLI, MCP, or the hosted assistant.
Local preview, checks, and export work without Samva credentials, except that a project importing your brand needs credentials or a pulled brand snapshot. Publishing creates an immutable publication from an exact commit; each publication keeps the brand version it was built with. Raw HTML and text sending remains available independently of templates.