[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/)

# Images

The build optimizes images automatically: every eligible `<img>` gets a responsive `srcset` of resized, format-converted variants, plus lazy-loading attributes. It's on by default, and you configure it (or turn it off) under the `images` key in `project.json`.

## Configuration

All properties are optional; these are the defaults:

```json&#x20;shiki
```

| Property        | What it controls                                                                              |
| --------------- | --------------------------------------------------------------------------------------------- |
| `optimize`      | Master switch; `false` disables all image processing                                          |
| `widths`        | Pixel widths for the responsive variants                                                      |
| `formats`       | Output formats (`"webp"`, `"avif"`, `"jpeg"`, `"png"`)                                        |
| `quality`       | Per-format compression quality (0–100)                                                        |
| `sizes`         | Fallback CSS `sizes`, used only when neither the tag nor its container says (below)           |
| `lazyLoad`      | Adds `loading="lazy"` and `decoding="async"`, whether or not `optimize` is on                 |
| `picture`       | Wrap a multi-format image in a `<picture>`, one `<source>` per format (default `true`)        |
| `service`       | `"build"` = Sharp at build time; `"cloudflare"` = transform URLs served by Cloudflare (below) |
| `remoteDomains` | Https hostnames whose remote images also get transform srcsets, `"cloudflare"` service only   |

## What the build does

For each eligible image, the pipeline (powered by [Sharp](https://sharp.pixelplumbing.com/)):

1. **Filters widths** to those at or below the image's natural width. There is no upscaling. The image's own width is added as an extra breakpoint only when it is *smaller* than your largest configured width. Otherwise your largest width is the ceiling you asked for, and a 3840 px screenshot would quietly emit a 3840 px variant in every format that no layout would ever request.
2. **Generates one variant per width × format** and writes it to `dist/images/_optimized/{stem}-{width}-{hash}.{format}` (e.g. `hero-640-a1b2c3d4.webp`).
3. **Rewrites the markup.** With one configured format, the `<img>` gets a `srcset` of those variants plus a `sizes` (below). With two or more, it is wrapped in a `<picture>`:

```html&#x20;shiki
```

The `<img>` carries no `srcset`, which is what makes it a real fallback. A bare `srcset` says nothing about format, so a browser that can't decode AVIF picks an AVIF candidate anyway and shows nothing; `<source type>` is the only markup that lets it decline. Set `"picture": false` if you'd rather have the flat `<img>` and accept that.

Its `src` is the largest variant in a universally decodable format (`jpeg` or `png`) when your `formats` include one, and the original file otherwise. `src` is only ever reached by a client that understood neither `srcset` nor any `<source type>`, so it has to stay decodable; but the original is the *unresized* source, and a resized variant of the same format is strictly better. With `formats: ["webp", "avif"]` there is nothing safe to point at, so the original stays: a smaller image nobody can decode is not an improvement.

## How `sizes` is chosen

`sizes` is a promise about layout, and the browser keeps it absolutely: it picks a candidate from that string before any layout has happened and never revisits the choice. One project-wide string therefore can't be right for every image on a site. `(max-width: 768px) 100vw, 50vw` describes a half-width image, and on a hero that renders full-width inside a 960 px column it is too small on a wide screen and too large on a narrow one.

So the build asks, in order:

1. **A `sizes` you wrote on the tag.** Always wins.
2. **The container.** The narrowest literal `max-width` or `width` in `px`/`rem` on the image or any ancestor, emitted as `(max-width: 960px) 100vw, 960px`. This is layout the build already knows, so it beats a project-wide guess.
3. **`images.sizes`**, if you set one.
4. **Nothing**, so the browser assumes `100vw`.

Only literal lengths count. A `clamp()`, a percentage, or a `var()` is a real constraint too, but not one the build can resolve, and a wrong `sizes` is worse than none. Write `sizes` on the tag when your layout is one of those.

Images embedded in pre-rendered Markdown content go through the same transformation, so a `![hero](./images/hero.jpg)` in a blog post is optimized like any hand-placed `<img>`.

## When images load

`loading` and `decoding` are decided by `lazyLoad` alone, for every image on the site, including ones the optimizer skipped, and every image in a project with `"optimize": false`. Whether an image is worth re-encoding says nothing about when it should be fetched.

Three things stop `loading="lazy"` from being added:

| You write                     | The build does                             |
| ----------------------------- | ------------------------------------------ |
| `"lazyLoad": false`           | Nothing, anywhere                          |
| `loading="eager"` or `"lazy"` | Leaves it exactly as you wrote it          |
| `fetchpriority="high"`        | Nothing; the two contradict and yours wins |

Tip

Mark your hero image&#x20;
`fetchpriority="high"`
. The build can't work out which image is the largest contentful paint, because that depends on the visitor's viewport rather than on the document, so it doesn't guess, and an unmarked hero is lazy-loaded like everything else.

## Which images are eligible

Processed: `<img>` nodes with a static, local `src` (a string, rather than a ${...} expression or a `$ref`) pointing at a raster file (`.jpg`, `.jpeg`, `.png`, `.webp`, `.avif`, `.tiff`) that exists on disk.

Skipped automatically:

- External URLs (`http://`, `https://`, `//`, `data:`)
- SVGs and GIFs
- Dynamic `src` values (template expressions or bindings)
- Anything carrying a `data-no-optimize` attribute

## Where srcs resolve

In pages, layouts, and components, image paths resolve against the **site root**, not the referring file: a `/`-prefixed src like `/images/hero.jpg` resolves into `public/` (so it's `public/images/hero.jpg` on disk, and works verbatim at runtime too), while a relative src like `content/blog/images/hero.jpg` resolves from the project root.

**Content entries are the exception.** They resolve against themselves, so a collection stays readable in a markdown editor:

```markdown&#x20;shiki
```

A relative reference in an entry is remapped to the collection's own URL, so `content/blog/images/diagram.png` becomes `/content/blog/images/diagram.png`, and the build copies the file there. A collection that declares `exclude`, `where` or `route` does not publish through that URL what its own rules leave out: an excluded file, a hidden file such as `.env` and a Markdown document are neither remapped nor copied, even when a page names `/content/<type>/...` directly. See [Content collections](/docs/framework/site/content-collections).

## Per-image overrides

Individual images can override the global config through ordinary attributes:

```json&#x20;shiki
```

- `sizes`: replaces the configured default for this image
- `loading="eager"`: keeps `loading="lazy"` off an above-the-fold image
- `fetchpriority="high"`: marks the LCP image: fetched at high priority, never lazy-loaded
- `data-no-optimize`: skips the pipeline entirely

## Caching

Variants are cached in `.cache/images/` (with a `manifest.json`) so unchanged images aren't re-encoded on the next build. The cache key combines the source file's content hash with a hash of the optimization config, so changing either the image or the `widths`/`formats`/`quality` settings invalidates the entry, as do missing variant files. The cache survives `dist/` cleanup; add `.cache/` to `.gitignore`, or commit it to speed up CI builds.

The cache is self-pruning: after a fully successful build, entries no build step touched (deleted or replaced source images, superseded configs) are dropped and their variant files deleted, so a persisted cache, and the `dist/images/_optimized/` copy made from it, stays bounded to the images the site actually uses, even when the cache lives forever (for example in a CI cache). Builds that end with errors skip pruning, because a page that failed to compile never touched its images and evicting them would force a pointless re-encode.

## The Cloudflare service

Setting `"service": "cloudflare"` replaces the build-time pipeline with pure markup: eligible images get a `srcset` of `/cdn-cgi/image/...` transform URLs (one per configured width, `format=auto` so Cloudflare negotiates AVIF/WebP per browser, quality from `quality.webp`), and no variants are generated at build time. Remote `https` images from hostnames listed in `remoteDomains` get the same treatment.

This requires the site to be served through a Cloudflare zone with Image Transformations enabled (dashboard: *Images > Transformations*). The URLs do not resolve on `*.pages.dev` or `*.workers.dev` preview hosts, so previews fall back to the untouched originals.

## Related

- [Build output and adapters](/docs/framework/site/deployment): where the variants land in `dist/`
- [Media in Studio](/docs/studio/projects/media): browsing and placing images visually
- [project.json](/docs/framework/site/project-json): the full configuration reference

✕

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.
