[Skip to content](#main-content)

[![Jx Suite](/favicon.svg)
Suite](/)Search⌘KESC

Jump to

[Install Jx Studio](/docs/start/install)[Build your first project](/docs/start/first-project)[Document format](/docs/framework/concepts/documents)[Formula catalog](/docs/framework/reference/formulas)

↵
select↑↓
navigateesc
close

[Studio](/studio)[Framework](/framework)[Templates](/templates)[Compare](/compare)[Docs](/docs/start/first-project)[GitHub](https://github.com/jxsuite/jx)[Download](/download)

✕

[Studio](/studio)[Framework](/framework)[Templates](/templates)[Compare](/compare)[Docs](/docs/start/first-project)[GitHub](https://github.com/jxsuite/jx)

Color scheme&#xA;

[Download](/download)

☰

Docs menu

Start here[Overview](/docs/start/)Get started[Install Jx Studio](/docs/start/install/)[Your first project](/docs/start/first-project/)[A tour of Jx Studio](/docs/start/studio-tour/)Tutorials[Tutorial: interactive component](/docs/start/first-component/)[Tutorial: blog with collections](/docs/start/first-collection/)[Video tutorials](/docs/start/videos/)Coming from another tool[Coming from WordPress](/docs/start/coming-from-wordpress/)[Coming from Webflow or Framer](/docs/start/coming-from-webflow/)[Coming from Wix or Squarespace](/docs/start/coming-from-wix/)[Coming from Lovable or Builder.io](/docs/start/coming-from-ai-builders/)Studio[Overview](/docs/studio/)[The desktop app](/docs/studio/desktop/)The workspace[Overview](/docs/studio/interface/)[Welcome screen](/docs/studio/interface/welcome-screen/)[Editors and views](/docs/studio/interface/modes/)[The canvas](/docs/studio/interface/canvas/)[Documents and panes](/docs/studio/interface/tabs/)[Quick Access](/docs/studio/interface/quick-access/)[Keyboard shortcuts](/docs/studio/interface/shortcuts/)[Preferences](/docs/studio/interface/preferences/)[Languages](/docs/studio/interface/languages/)[Problems and progress](/docs/studio/interface/problems-and-progress/)[Commands](/docs/studio/interface/commands/)Projects[Overview](/docs/studio/projects/)[Create a project](/docs/studio/projects/create/)[Pages, layouts, components](/docs/studio/projects/pages-layouts-components/)[The Content workspace](/docs/studio/projects/browse/)[Starter templates](/docs/studio/projects/starters/)[Media](/docs/studio/projects/media/)[Content types](/docs/studio/projects/content-types/)[Project settings](/docs/studio/projects/settings/)[Dependencies and imports](/docs/studio/projects/dependencies/)Edit mode[Overview](/docs/studio/editing/)[Writing and formatting](/docs/studio/editing/writing/)[Slash commands](/docs/studio/editing/slash-commands/)[Frontmatter and metadata](/docs/studio/editing/frontmatter/)[Grid mode](/docs/studio/editing/grid/)Design mode[Overview](/docs/studio/design/)[Outline](/docs/studio/design/layers/)[Insert](/docs/studio/design/elements/)[Content tab](/docs/studio/design/properties/)[Style inspector](/docs/studio/design/style-inspector/)[Breakpoints](/docs/studio/design/breakpoints/)[States and selectors](/docs/studio/design/states-and-selectors/)[Design tokens](/docs/studio/design/tokens/)[Project Styles](/docs/studio/design/stylebook/)[Working with components](/docs/studio/design/components/)[Repeaters](/docs/studio/design/repeaters/)Logic[Overview](/docs/studio/logic/)[Formulas and expressions](/docs/studio/logic/formulas/)[Formula workspace](/docs/studio/logic/formula-workspace/)[Statements](/docs/studio/logic/statements/)[Logic tab](/docs/studio/logic/events/)[Data](/docs/studio/logic/data/)[Data sources](/docs/studio/logic/data-sources/)[Code editing](/docs/studio/logic/code/)Databases[Overview](/docs/studio/data/)[Connections](/docs/studio/data/connections/)[Data tables](/docs/studio/data/tables/)[Data grid](/docs/studio/data/grid/)[Auth and secrets](/docs/studio/data/auth-and-secrets/)AI assistant[Overview](/docs/studio/ai/)[The AI assistant](/docs/studio/ai/chat/)[Document assistant](/docs/studio/ai/document-assistant/)Publish[Overview](/docs/studio/publish/)[Source control](/docs/studio/publish/source-control/)[GitHub](/docs/studio/publish/github/)[Cloudflare Pages](/docs/studio/publish/cloudflare/)[Other hosts](/docs/studio/publish/other-hosts/)[Redirects](/docs/studio/publish/redirects/)[Real-time collaboration](/docs/studio/publish/collaboration/)Framework[Overview](/docs/framework/)Concepts[Documents](/docs/framework/concepts/documents/)[Elements](/docs/framework/concepts/elements/)[Components](/docs/framework/concepts/components/)[Props and scope](/docs/framework/concepts/props-and-scope/)[State](/docs/framework/concepts/state/)[Reactivity](/docs/framework/concepts/reactivity/)[References](/docs/framework/concepts/references/)[Expressions](/docs/framework/concepts/expressions/)[Statements](/docs/framework/concepts/statements/)[Functions and sidecars](/docs/framework/concepts/functions/)[Styling](/docs/framework/concepts/styling/)[Color schemes](/docs/framework/concepts/color-schemes/)[Popovers and overlays](/docs/framework/concepts/overlays/)[Accessibility](/docs/framework/concepts/accessibility/)[Lists and iteration](/docs/framework/concepts/lists/)[Data prototypes](/docs/framework/concepts/data-prototypes/)[Timing](/docs/framework/concepts/timing/)[Dynamic switching](/docs/framework/concepts/switching/)[Security](/docs/framework/concepts/security/)Site architecture[Overview](/docs/framework/site/)[project.json](/docs/framework/site/project-json/)[Routing](/docs/framework/site/routing/)[Layouts](/docs/framework/site/layouts/)[Content collections](/docs/framework/site/content-collections/)[Jx Markdown](/docs/framework/site/jx-markdown/)[Obsidian vault as content](/docs/framework/site/obsidian-vault/)[Relationships](/docs/framework/site/relationships/)[SEO and metadata](/docs/framework/site/seo/)[Locales and languages](/docs/framework/site/i18n/)[Images](/docs/framework/site/images/)[Redirects](/docs/framework/site/redirects/)[Feeds](/docs/framework/site/feeds/)[Site search](/docs/framework/site/search/)[Build output and adapters](/docs/framework/site/deployment/)How compilation works[Overview](/docs/framework/build/)[The dev server](/docs/framework/build/dev-server/)[CLI commands](/docs/framework/build/cli/)Working with agents[Overview](/docs/framework/agents/)[Authoring rules for agents](/docs/framework/agents/authoring-rules/)[Machine-readable docs](/docs/framework/agents/machine-readable/)Reference[Overview](/docs/framework/reference/)[Formula catalog](/docs/framework/reference/formulas/)[Operator reference](/docs/framework/reference/operators/)Extending[Overview](/docs/extending/)Extensions[Extension anatomy](/docs/extending/extensions/anatomy/)[Schema composition](/docs/extending/extensions/schema-composition/)[Custom classes](/docs/extending/extensions/classes/)[Custom formats](/docs/extending/extensions/formats/)[Capability methods](/docs/extending/extensions/capabilities/)[Project sections](/docs/extending/extensions/project-sections/)[Server mounts](/docs/extending/extensions/server/)[Connectors](/docs/extending/extensions/connectors/)[Search indexes](/docs/extending/extensions/search/)[Security and secrets](/docs/extending/extensions/security/)[Tutorial: a TOML format](/docs/extending/extensions/tutorial-toml-format/)[Tutorial: a guestbook](/docs/extending/extensions/tutorial-guestbook/)[First-party extensions](/docs/extending/extensions/first-party/)Embedding[Overview](/docs/extending/embedding/)[Hosting the Studio assets](/docs/extending/embedding/hosting/)[Writing a platform adapter](/docs/extending/embedding/platform-adapter/)[The backend protocol](/docs/extending/embedding/backend-protocol/)[Dev server internals](/docs/extending/embedding/dev-server/)[Embedding the runtime in your app](/docs/extending/embedding/runtime-host/)[Writing assistant tools](/docs/extending/embedding/assistant-harness/)UI kit[The Jx UI kit](/docs/extending/ui-kit/)Reference[Protocol routes](/docs/extending/reference/studio-routes/)[Implementation status](/docs/extending/reference/implementation-status/)[Spec changelog](/docs/extending/reference/spec-changelog/)[Standards alignment](/docs/extending/reference/standards/)Contributing[Working in the monorepo](/docs/extending/contributing/monorepo/)[Contributing to these docs](/docs/extending/contributing/docs/)[AI assistant evals](/docs/extending/contributing/ai-evals/)

# Tutorial: a blog with content collections

In this tutorial you give your site a blog the structured way: a `posts` content type with a field schema, three entries created from it, a round of bulk editing in Grid mode, and a Blog page that lists every post from live data. Add a fourth post next month and the page updates itself.

![The Blog page in Preview, listing three post cards with titles, dates, and descriptions](/content/docs/images/blog-finished.png)

**About 20 minutes.** Before you start:

- Have a project open in Jx Studio. **[Your first project](/docs/start/first-project)** gets you there.
- Knowing your way around the canvas and panels helps; **[Tutorial: your first interactive component](/docs/start/first-component)** is the gentlest way in, but isn't required.

## 1. Create the posts content type

A content type is your CMS schema: where a collection's entries live, and what fields each one carries.

1. Open the **Settings** menu in the Command Bar and pick **Open Project Settings › Content Types**. (⌘K and **Open Project Settings** gets you to the same place.)
2. Click **New content type** at the bottom of the type list.
3. Type `Posts` and click **Create**.

![The Content Types section with the new posts type selected and its empty field schema](/content/docs/images/blog-content-type.png)

You should see the new type selected, named `posts`, with a matching source folder (`content/posts/`) and an empty field schema ready to fill.

Tip

**Add new › Collection**
&#x20;(
⌘N
) does steps 1 and 2 in one go, from a set of common fields, and can create the page each post opens at as well. This tutorial builds the type by hand so you see every part of it. See&#x20;
**[Content types](/docs/studio/projects/content-types#create-a-content-type)**
.

## 2. Give it fields

Add three fields. For each one, click **Add Field**, type the name, pick its type, and click **Add**:

1. `title`, type **string**, with the **Required** switch on.
2. `date`, type **string**, format **date**, so entries get a proper date field.
3. `description`, type **string**.

![The posts type with title, date, and description rows in its field schema](/content/docs/images/blog-schema-fields.png)

You should now see three field rows in the schema. These become the form every post fills in. Leave **Source** and **Format** as they are, and close Settings. Everything else the builder can do, from nested fields to references between types, is in **[Content types](/docs/studio/projects/content-types)**.

## 3. Create your first post

1. Press ⌘N to open **Add new** (in a browser, ⌘⌥N).
2. Choose **Entry** in the list on the left. It appears now that your project has a content type, and **Posts** is already picked as its collection.
3. Type `Hello World` and click **Create entry**.

![The Content workspace showing a collection as cards with live previews, with the Collections panel on the left](/content/docs/images/mode-manage.png)

Studio creates `content/posts/hello-world.md` with every schema field pre-filled (the title with the name you typed, the rest with a sensible blank) and opens it in the [Content workspace](/docs/studio/projects/browse), where **Posts** is now listed in the Collections panel on the left.

## 4. Fill it in

The post opens on the canvas, inside your site's template: the banner above it says the text is yours to write and the layout is locked. Its fields are on the right, in the Inspector's **Entry** tab:

1. Check that **title** says `Hello World`.
2. Pick today in the **date** field.
3. Give **description** a sentence: `The first post on my brand-new blog.`

Then click into the page below and write a paragraph or two of body text.

![Jx Studio editing markdown content inline with a WYSIWYG editor](/content/docs/images/mode-edit.png)

You should see the fields filled in and your words on the page. See **[Write an entry](/docs/studio/projects/browse#write-an-entry)** for the rest of the Entry tab.

## 5. Add two more posts

Repeat step 3 twice, naming them `Grid mode rocks` and `Hello again` (or anything you like). This time skip the other fields on purpose; you'll fill them in bulk next.

You should now have three entries under **Posts** in the Collections panel, two of them with nothing but a title.

## 6. Open the collection as a grid

Editing entries one file at a time doesn't scale, so Studio can open the whole collection as a spreadsheet:

1. Click **Posts** in the Collections panel, then click **Edit in grid** in the toolbar above the list. (The same action is on the right-click menu of the `content/posts` folder in the Files panel, as **Edit Collection in Grid**.)
2. The grid opens in the Content workspace, beside your posts. A view you save there is listed under **Posts** in the Collections panel next time.

![The posts collection open in Grid mode, one row per entry with title, date, and description columns](/content/docs/images/blog-grid.png)

You should see one row per post and one column per schema field, with the **Path** column pinned at the left, and your two blank rows plain to see.

## 7. Fill in the blanks and save

1. Double-click each empty **title** cell and type one. Cells are typed, so **date** cells give you a date field.
2. Fill in the **date** and **description** cells the same way. Edited cells are highlighted, and nothing touches your files yet.
3. Click **Save**, which counts your pending changes, or press ⌘S (macOS) or Ctrl+S (Windows/Linux).

Studio writes every change in one batch and reports what saved. Ranges, fill-down, and find & replace are covered in **[Grid mode](/docs/studio/editing/grid)**.

Note

Saving a collection row rewrites that file's frontmatter block, which is exactly what fills in your blank entries here.

## 8. Create the Blog page

1. Press ⌘N to open **Add new** again (in a browser, ⌘⌥N), keep **Page**, type `Blog` and click **Create page**. Studio writes the page and opens it at your site's `/blog` address.
2. In the **View** control on the pane's context bar, click **Design**.

You should see the empty page on the design canvas, once per breakpoint.

## 9. Design one post card

Design a single card, which the repeater will copy per post:

1. Press ⌘K and run **Show Insert**. With nothing selected, click the **article** card.
2. With the article selected, click the **h3** card, then the **p** card twice. Each new element lands inside the selection.
3. Select each of the three in turn and give it placeholder text via **Text Content** in the Inspector's **Content** tab: `Post title`, `A line about the post.`, and `2026-01-01`.

![The design canvas with one article card holding a heading and two placeholder paragraphs](/content/docs/images/blog-card.png)

You should see one plausible-looking post card on the canvas. Style it as much or as little as you like; **[Design mode](/docs/studio/design)** covers the tools.

## 10. Query the collection from state

The page needs the posts as data it can render:

1. Click **Data** on the Navigator rail to open the **Data** panel, then click the **+ Add…** picker.
2. Pick **ContentCollection**, listed with the sources your project's imports and extensions provide.
3. Rename the new entry to `posts` (type the name and press Enter).
4. Set **contentType** to `posts`, and add a **sort** rule on the `date` field with order `desc`, so the newest post lists first.

![The Data panel editing a ContentCollection entry with contentType posts and a date sort rule](/content/docs/images/blog-collection-state.png)

Open the **Data** panel and you should see `posts` worth `Array(3)`, which is your three entries, live. Filters, limits, and the other sources are covered in **[Data sources](/docs/studio/logic/data-sources)**.

## 11. Repeat the card for every post

1. Right-click the article, on the canvas or in **Outline**, and choose **Repeat…**.
2. In the dialog, set **Items source** to `posts`.
3. Click **Create Repeater**.

![The Repeat dialog with posts chosen as the items source](/content/docs/images/blog-repeat-dialog.png)

Your card is now the repeater's *template*, marked **↻** in Outline. On the design canvas it still renders once, which is the template view. Everything about repeaters lives in **[Repeaters](/docs/studio/design/repeaters)**.

## 12. Bind the card to each post's fields

Inside the template, each post's data is in scope:

1. Double-click the heading, select the placeholder text, and delete it.
2. Click **Insert data** on the floating toolbar and pick `item.data.title`. A live placeholder lands in the text.
3. Do the same for the two paragraphs: `item.data.description` and `item.data.date`.

![The Insert data list open over the card's heading, offering item.data fields](/content/docs/images/blog-insert-data.png)

Each text now holds a placeholder that fills itself from the current post. (A collection entry's schema fields live under `item.data`; `item` and `index` are there too.)

## 13. Preview and save

Pick **Preview** in the **View** control on the context bar.

![Preview on, the single card expanded into three post cards with real titles, dates, and descriptions](/content/docs/images/blog-preview.png)

You should see the single card expand into three, newest first, each filled in from its own post. Switch the **View** control back to **Design**, then save your open documents with ⌘S / Ctrl+S. When you're ready, publish the lot from the **Publish** workspace's **Review changes** (⌘5). See **[Source control](/docs/studio/publish/source-control)**.

![The publish card in Review changes: the destination, the summary and the publish button](/content/docs/images/git-commit.png)

## Give each post its own page

The listing links nowhere yet, and that's deliberate: one page per post is the job of a *dynamic page*, a single page file with a parameter in its name (like `[slug]`) that the build expands into one page per entry of the collection. That wiring lives in the page's own format rather than a Studio panel today; **[Routing](/docs/framework/site/routing)** shows the exact file, and **[Content collections](/docs/framework/site/content-collections)** covers looking up "the entry this URL names". Once a dynamic page exists, Studio meets you halfway: opening it puts a picker per URL parameter in the context bar's **resolving with** popover, so the canvas previews a real post instead of a placeholder.

## What you built

A complete content pipeline, end to end:

- A **content type** (`posts`) gives you schema-backed entries with one-click creation from **New post** in the Content workspace.
- **Three entries**, edited both one at a time (the Inspector's **Entry** tab) and in bulk (**Grid mode**).
- A **ContentCollection** state entry is the collection as live, sorted data on a page.
- A **repeater** whose template binds `item.data` fields is one designed card, rendered per post.

Note

On disk this is all plain files: your types in the&#x20;
`content`
&#x20;section of&#x20;
`project.json`
, one file per post in&#x20;
`content/posts/`
, and the Blog page holding the query and the repeater. The formats are documented in&#x20;
**[Content collections](/docs/framework/site/content-collections)**
&#x20;and&#x20;
**[Lists](/docs/framework/concepts/lists)**
.

## Next steps

- Turn the post card into a reusable component with **[Working with components](/docs/studio/design/components)**.
- Add an author type and point posts at it with a **reference** field: **[Content types](/docs/studio/projects/content-types)** and **[Relationships](/docs/framework/site/relationships)**.
- Give posts their own pages with a dynamic route, described in **[Routing](/docs/framework/site/routing)**.
- Publish it, following **[Publish](/docs/studio/publish)**.

✕

Start here[Overview](/docs/start/)Get started[Install Jx Studio](/docs/start/install/)[Your first project](/docs/start/first-project/)[A tour of Jx Studio](/docs/start/studio-tour/)Tutorials[Tutorial: interactive component](/docs/start/first-component/)[Tutorial: blog with collections](/docs/start/first-collection/)[Video tutorials](/docs/start/videos/)Coming from another tool[Coming from WordPress](/docs/start/coming-from-wordpress/)[Coming from Webflow or Framer](/docs/start/coming-from-webflow/)[Coming from Wix or Squarespace](/docs/start/coming-from-wix/)[Coming from Lovable or Builder.io](/docs/start/coming-from-ai-builders/)Studio[Overview](/docs/studio/)[The desktop app](/docs/studio/desktop/)The workspace[Overview](/docs/studio/interface/)[Welcome screen](/docs/studio/interface/welcome-screen/)[Editors and views](/docs/studio/interface/modes/)[The canvas](/docs/studio/interface/canvas/)[Documents and panes](/docs/studio/interface/tabs/)[Quick Access](/docs/studio/interface/quick-access/)[Keyboard shortcuts](/docs/studio/interface/shortcuts/)[Preferences](/docs/studio/interface/preferences/)[Languages](/docs/studio/interface/languages/)[Problems and progress](/docs/studio/interface/problems-and-progress/)[Commands](/docs/studio/interface/commands/)Projects[Overview](/docs/studio/projects/)[Create a project](/docs/studio/projects/create/)[Pages, layouts, components](/docs/studio/projects/pages-layouts-components/)[The Content workspace](/docs/studio/projects/browse/)[Starter templates](/docs/studio/projects/starters/)[Media](/docs/studio/projects/media/)[Content types](/docs/studio/projects/content-types/)[Project settings](/docs/studio/projects/settings/)[Dependencies and imports](/docs/studio/projects/dependencies/)Edit mode[Overview](/docs/studio/editing/)[Writing and formatting](/docs/studio/editing/writing/)[Slash commands](/docs/studio/editing/slash-commands/)[Frontmatter and metadata](/docs/studio/editing/frontmatter/)[Grid mode](/docs/studio/editing/grid/)Design mode[Overview](/docs/studio/design/)[Outline](/docs/studio/design/layers/)[Insert](/docs/studio/design/elements/)[Content tab](/docs/studio/design/properties/)[Style inspector](/docs/studio/design/style-inspector/)[Breakpoints](/docs/studio/design/breakpoints/)[States and selectors](/docs/studio/design/states-and-selectors/)[Design tokens](/docs/studio/design/tokens/)[Project Styles](/docs/studio/design/stylebook/)[Working with components](/docs/studio/design/components/)[Repeaters](/docs/studio/design/repeaters/)Logic[Overview](/docs/studio/logic/)[Formulas and expressions](/docs/studio/logic/formulas/)[Formula workspace](/docs/studio/logic/formula-workspace/)[Statements](/docs/studio/logic/statements/)[Logic tab](/docs/studio/logic/events/)[Data](/docs/studio/logic/data/)[Data sources](/docs/studio/logic/data-sources/)[Code editing](/docs/studio/logic/code/)Databases[Overview](/docs/studio/data/)[Connections](/docs/studio/data/connections/)[Data tables](/docs/studio/data/tables/)[Data grid](/docs/studio/data/grid/)[Auth and secrets](/docs/studio/data/auth-and-secrets/)AI assistant[Overview](/docs/studio/ai/)[The AI assistant](/docs/studio/ai/chat/)[Document assistant](/docs/studio/ai/document-assistant/)Publish[Overview](/docs/studio/publish/)[Source control](/docs/studio/publish/source-control/)[GitHub](/docs/studio/publish/github/)[Cloudflare Pages](/docs/studio/publish/cloudflare/)[Other hosts](/docs/studio/publish/other-hosts/)[Redirects](/docs/studio/publish/redirects/)[Real-time collaboration](/docs/studio/publish/collaboration/)Framework[Overview](/docs/framework/)Concepts[Documents](/docs/framework/concepts/documents/)[Elements](/docs/framework/concepts/elements/)[Components](/docs/framework/concepts/components/)[Props and scope](/docs/framework/concepts/props-and-scope/)[State](/docs/framework/concepts/state/)[Reactivity](/docs/framework/concepts/reactivity/)[References](/docs/framework/concepts/references/)[Expressions](/docs/framework/concepts/expressions/)[Statements](/docs/framework/concepts/statements/)[Functions and sidecars](/docs/framework/concepts/functions/)[Styling](/docs/framework/concepts/styling/)[Color schemes](/docs/framework/concepts/color-schemes/)[Popovers and overlays](/docs/framework/concepts/overlays/)[Accessibility](/docs/framework/concepts/accessibility/)[Lists and iteration](/docs/framework/concepts/lists/)[Data prototypes](/docs/framework/concepts/data-prototypes/)[Timing](/docs/framework/concepts/timing/)[Dynamic switching](/docs/framework/concepts/switching/)[Security](/docs/framework/concepts/security/)Site architecture[Overview](/docs/framework/site/)[project.json](/docs/framework/site/project-json/)[Routing](/docs/framework/site/routing/)[Layouts](/docs/framework/site/layouts/)[Content collections](/docs/framework/site/content-collections/)[Jx Markdown](/docs/framework/site/jx-markdown/)[Obsidian vault as content](/docs/framework/site/obsidian-vault/)[Relationships](/docs/framework/site/relationships/)[SEO and metadata](/docs/framework/site/seo/)[Locales and languages](/docs/framework/site/i18n/)[Images](/docs/framework/site/images/)[Redirects](/docs/framework/site/redirects/)[Feeds](/docs/framework/site/feeds/)[Site search](/docs/framework/site/search/)[Build output and adapters](/docs/framework/site/deployment/)How compilation works[Overview](/docs/framework/build/)[The dev server](/docs/framework/build/dev-server/)[CLI commands](/docs/framework/build/cli/)Working with agents[Overview](/docs/framework/agents/)[Authoring rules for agents](/docs/framework/agents/authoring-rules/)[Machine-readable docs](/docs/framework/agents/machine-readable/)Reference[Overview](/docs/framework/reference/)[Formula catalog](/docs/framework/reference/formulas/)[Operator reference](/docs/framework/reference/operators/)Extending[Overview](/docs/extending/)Extensions[Extension anatomy](/docs/extending/extensions/anatomy/)[Schema composition](/docs/extending/extensions/schema-composition/)[Custom classes](/docs/extending/extensions/classes/)[Custom formats](/docs/extending/extensions/formats/)[Capability methods](/docs/extending/extensions/capabilities/)[Project sections](/docs/extending/extensions/project-sections/)[Server mounts](/docs/extending/extensions/server/)[Connectors](/docs/extending/extensions/connectors/)[Search indexes](/docs/extending/extensions/search/)[Security and secrets](/docs/extending/extensions/security/)[Tutorial: a TOML format](/docs/extending/extensions/tutorial-toml-format/)[Tutorial: a guestbook](/docs/extending/extensions/tutorial-guestbook/)[First-party extensions](/docs/extending/extensions/first-party/)Embedding[Overview](/docs/extending/embedding/)[Hosting the Studio assets](/docs/extending/embedding/hosting/)[Writing a platform adapter](/docs/extending/embedding/platform-adapter/)[The backend protocol](/docs/extending/embedding/backend-protocol/)[Dev server internals](/docs/extending/embedding/dev-server/)[Embedding the runtime in your app](/docs/extending/embedding/runtime-host/)[Writing assistant tools](/docs/extending/embedding/assistant-harness/)UI kit[The Jx UI kit](/docs/extending/ui-kit/)Reference[Protocol routes](/docs/extending/reference/studio-routes/)[Implementation status](/docs/extending/reference/implementation-status/)[Spec changelog](/docs/extending/reference/spec-changelog/)[Standards alignment](/docs/extending/reference/standards/)Contributing[Working in the monorepo](/docs/extending/contributing/monorepo/)[Contributing to these docs](/docs/extending/contributing/docs/)[AI assistant evals](/docs/extending/contributing/ai-evals/)

[![Jx Suite](/favicon.svg)
Suite](/)The visual IDE for the web. Build any website, save it as plain files, own it forever. MIT licensed.

Product

[Studio](/studio)[Download](/download)[Templates](/templates)[Features](/features)[Compare](/compare)[Jx Cloud (soon)](/cloud)

Developers

[Docs](/docs/start/first-project)[Framework](/framework)[Get Studio](/docs/start/install)[Spec](/docs/framework)[GitHub](https://github.com/jxsuite/jx)

Project

[MIT License](https://github.com/jxsuite/jx/blob/main/LICENSE)[Releases](https://github.com/jxsuite/jx/releases/latest)[Privacy](/privacy)[Terms](/terms)[Support](/support)

Built with Jx Suite. © 2026 Avunu LLC. Open source under the MIT License.
