Skip to content

Quick start

You need Matter running on your computer and signed in, and Node with npm for your extension’s build.

The matter command comes with Matter. Add its folder to your shell’s PATH, for example in ~/.zshrc:

Terminal window
export PATH="$HOME/.matter/bin:$PATH"

On Windows, add %USERPROFILE%\.matter\bin to your Path.

Agent threads in Matter already have it, so you can also ask an agent to run these commands. matter extension --help lists every command.

Terminal window
matter extension create pipeline --space Sales --name "Pipeline" --icon 📈
cd pipeline

This creates the extension in the space, and scaffolds an empty project in the folder you name (the current folder if you leave it out):

  • matter.json: the manifest, with the new extension’s id and the oldest Matter it runs on;
  • schema.json: the tables the extension needs;
  • package.json for Vite, TypeScript and the SDK (@matter.work/extension-sdk), vite.config.ts with the SDK plugin, and tsconfig.json;
  • index.html, src/main.ts and src/style.css: a page that greets the member in Matter’s theme;
  • .gitignore and a README.

With --worker, it adds a worker too, in src/worker.ts.

Then it writes src/matter-extension.d.ts, the types for your space’s tables (the same as matter extension types). The dev server gets a port of the extension’s own, between 5200 and 5799, so it doesn’t collide with other projects. create never overwrites a file that’s already there.

You can also create an extension in Matter itself: choose New extension in the space’s settings under Extensions, or the + beside the sidebar’s Extensions heading once the space has an extension. Deploy to it from a project with matter extension deploy --extension <id>, or put its id in matter.json as extension.

Terminal window
npm install
matter extension dev

matter extension dev starts your dev server (dev.command in matter.json), waits for it to answer, and shows it in Matter in place of the deployed extension. Open the extension from the sidebar. Changes reload as you save, and the extension’s header shows a Dev pill with the dev server’s address. Press Ctrl-C to stop: the extension goes back to its deployment. To keep it running after you close the terminal, use matter extension dev --background, and matter extension dev --stop later.

This works before the extension’s first deploy too: until then, Matter shows only your dev server.

Describe the tables in schema.json and apply it:

{
"tables": [
{
"name": "Deals",
"fields": [
{ "name": "Name", "type": "title" },
{ "name": "Stage", "type": "select", "options": ["Lead", "Won", "Lost"] },
{ "name": "Amount", "type": "number" }
],
"indexes": [
{ "name": "by_stage", "match": ["Stage"], "order": [{ "field": "Amount", "direction": "desc" }] }
]
}
]
}
Terminal window
matter table apply schema.json

It creates what’s missing in the extension’s space and changes nothing else. While matter extension dev runs, your types follow the tables, so matter.table('Deals') is typed a few seconds later. See Tables and indexes.

In src/main.ts:

import matter from '@matter.work/extension-sdk'
const deals = matter.table('Deals')
const root = document.querySelector<HTMLElement>('#extension')!
const list = document.createElement('ul')
const add = Object.assign(document.createElement('button'), { textContent: 'Add a lead' })
root.append(add, list)
// A live read: it answers now, and again whenever the leads change.
deals.watch({ index: 'by_stage', eq: { Stage: 'Lead' }, limit: 50 }, (state) => {
if (state.status !== 'ready') return
list.replaceChildren(
...state.value.rows.map((row) => Object.assign(document.createElement('li'), { textContent: row.title })),
)
})
add.onclick = () => deals.insert({ title: 'Acme', values: { Stage: 'Lead', Amount: 12000 } })

A new row appears in the list at once, and in the table in Matter. Its title is its Name: reads give it as row.title and as row.values.Name.

Every version is signed with a key of yours. Make one, once:

Terminal window
matter keys create

It asks for a passphrase, which you can leave empty, and registers the key in your workspace. See Signing keys. Then:

Terminal window
matter extension deploy -m "First version"

This runs your build, signs and uploads the deploy folder and makes it the current version. Members trust your key the first time they open one of your extensions; you never need to. Everyone in the space who opens the extension gets it. Deploy again after each change. See Developing, previewing and shipping for previews and rollbacks.