svelte.landing Open editor

framework/svelte

Svelte Online IDE and Editor with Runes and Live Preview

Write Svelte 5 the way the compiler intends — runes for state, styles scoped without asking, transitions built in — and watch it compile to plain JavaScript in the same tab you wrote it in.

versionSvelte 5
staterunes
stylesscoped by default
runtimecompiled away
Counter.sveltecart.svelte.ts
<script>
  let count = $state(0)
  let doubled = $derived(count * 2)
</script>

<button onclick={() => count++}>
  {count}{doubled}
</button>

<style>
  button { font: inherit }
</style>
compiled in 5ms

01 platform

What the Svelte compiler does differently

Svelte is the framework that argues it should not be in your bundle. Running it in a browser makes that argument concrete rather than theoretical.

  • The framework compiles away

    There is no virtual DOM and no runtime library shipped alongside your components. A .svelte file becomes plain JavaScript that mutates the DOM directly, and you can watch that happen here.

  • Runes make reactivity explicit

    Svelte 5 replaced the implicit rule that a top-level let was reactive with $state, $derived, $effect and $props. What updates is now something you declare rather than something you infer.

  • Styles are scoped without asking

    A <style> block inside a component applies to that component only, with no naming convention, no CSS-in-JS and no configuration. It is the default rather than an opt-in.

  • Transitions ship with the framework

    svelte/transition and svelte/motion are part of Svelte rather than a library you choose. Fade, fly, spring and tween are available the moment a project opens.

02 deep dive

Reactivity you declare rather than infer

Runes are the single largest change in Svelte's history, and the thing every Svelte 4 developer has to relearn. They are compiler symbols, not function calls, which is why the $ is syntax rather than a naming convention.

$state creates a reactive value. Mutate it or reassign it and everything that reads it updates. Deep objects are proxied, so mutating a nested field is tracked.

$derived is always consistent. It recomputes from its dependencies rather than being assigned, which removes the whole category of bug where a derived value drifts out of step with its source.

$props() replaced export let. Destructuring gives you defaults and full TypeScript inference in one place, rather than a list of exported variables the compiler treated specially.

$state.raw exists for the large cases. Deep proxying costs something on a ten-thousand-row array you always replace wholesale, so the raw variant skips it and tracks reassignment only.

state
$state / $state.raw
derived
$derived
effects
$effect
props
$props()
Cart.svelte
<script lang="ts">
  let { items = [] } = $props()

  let total = $derived(
    items.reduce((n, i) => n + i.price, 0)
  )
</script>

03 pipeline

What the compiler does to a .svelte file

Four stages between saving a file and seeing it render, all in the browser. Svelte is a compiler first, so knowing what it produces is most of understanding the framework.

  1. Parse the component

    Markup, <script> and <style> are read as one unit. A .svelte file is a single component by definition, which is why there is no registration step anywhere.

  2. Resolve the runes

    $state, $derived and $effect are compiler symbols, so this is where they become real update code rather than function calls left for a runtime to interpret.

  3. Scope the styles

    Every selector in the <style> block gets a component-specific attribute. Two components can both style .card and neither leaks into the other.

  4. Emit plain JavaScript

    What comes out is a module that creates and updates DOM nodes directly. There is no framework runtime beside it to interpret a component tree, which is the whole Svelte argument.

04 deep dive

Reactive state that lives outside a component

The change most people miss in Svelte 5 is not the syntax. It is that reactivity stopped being trapped inside .svelte files.

.svelte.ts and .svelte.js files can use runes. A shared cart, a session, a theme — declare $state in a plain module and import it anywhere. No store, no subscription, no $ prefix at the call site.

That replaces most of what stores were for. Svelte's writable stores still work and still matter for streams, but the common case of shared mutable state is now a variable in a module.

It composes like ordinary code. Because the state is just an export, a function that manipulates it is just a function. There is no special container to register it in.

The compiler still does the work. The file extension is what tells it to look for runes, which is why the naming matters and why an ordinary .ts file will not compile them.

modules
.svelte.ts / .svelte.js
shared state
exported $state
stores
still supported
prefix
none needed
cart.svelte.ts
export const cart = $state({ items: [] })

export function add(item) {
  cart.items.push(item)
}

05 features

What ships with a Svelte project

Everything below is active the moment the Svelte editor opens. Nothing here needs a plugin chosen or a config file written.

  • Svelte 5 with runes

    $state, $derived, $effect and $props compile as the framework implements them, including the .svelte.ts module form for shared state.

  • Scoped styles and preprocessors

    <style> scopes automatically, and lang="scss" goes through Dart Sass in the browser. Two components styling .card never collide.

  • Transitions and motion

    svelte/transition and svelte/motion are built in — fade, fly, slide, spring and tween — because they ship with the framework rather than beside it.

  • Snippets instead of slots

    Svelte 5 replaced slots with {#snippet} and {@render}, which are ordinary values you can pass as props. Both compile here.

  • TypeScript in any block

    <script lang="ts"> strips annotations at compile. Typed props through $props() cost nothing extra.

  • Any npm package

    Search, click install, import by name. XCODX resolves through esm.sh and writes a native import map, so no node_modules is ever populated.

06 workflow

From an empty tab to a mounted component

No npx sv create, no dependency install, no dev server. This is the whole loop, start to running.

session
  • new project → Svelte
  • App.svelte, main.ts, index.html
  • npm i svelte-motion
  • resolved via esm.sh · import map updated
  • save → Counter.svelte
  • compile 5ms · styles scoped s-1f4a
  • mounted · no runtime shipped
  • Compilation is the only step

    No bundler and no dev server sit between saving and rendering. The compiler runs in the browser and the component swaps in place.

  • The output is plain JavaScript

    What mounts is a module that touches the DOM directly, which is why a Svelte preview feels different from a framework that interprets a tree at runtime.

  • It keeps working offline

    XCODX installs as a Progressive Web App and the compiler runs on your device, so the loop survives losing the connection.

07 ecosystem

A project that mixes compilers

A .svelte file can sit beside a .vue one and a Python script; XCODX picks the compiler per file rather than per project.

  • React
  • Vue
  • Angular
  • Svelte
  • SolidJS
  • Lit
  • HTMX
  • Vite
  • TypeScript
  • JavaScript
  • HTML
  • CSS
  • SCSS
  • Less
  • Pug
  • Tailwind
  • Bootstrap
  • Vuetify
  • Ant Design
  • shadcn/ui
  • Phaser
  • Node.js
  • Python
  • Java
  • C++
  • C#
  • Go
  • Rust
  • Ruby
  • PHP
  • Kotlin
  • Swift
  • SQL
  • Bash

08 languages

Every language the editor knows

Highlighting and IntelliSense cover 70+ languages. These are the ones XCODX also compiles or executes for you.

Compiled in your browser11

Zero build step. Transform runs on a Web Worker, so typing never blocks.

  • JSX
  • TSX
  • TypeScript
  • Vue SFC
  • Svelte
  • Angular (JIT)
  • SolidJS
  • SCSS
  • Sass
  • Less
  • Pug

Rendered natively8

Straight to the live preview, no transform in the way.

  • HTML
  • CSS
  • JavaScript
  • JSON
  • Markdown
  • Jupyter (.ipynb)
  • SVG
  • YAML

Executed on demand22

70+ languages run through a self-hosted Piston engine. stdout, stderr, images and tracebacks land in the console.

  • Python
  • Java
  • C
  • C++
  • C#
  • Go
  • Rust
  • Ruby
  • PHP
  • Kotlin
  • Swift
  • Lua
  • Scala
  • Perl
  • Haskell
  • Elixir
  • Dart
  • R
  • Julia
  • SQLite
  • Bash
  • PowerShell

09 questions

Svelte on XCODX — common questions

The questions that decide whether this fits your work.

Which version of Svelte does this compile?

Svelte 5, the runes-era release that has been stable since late 2024. $state, $derived, $effect and $props all compile, as do snippets, and Svelte 4 components using the older reactive syntax still work because Svelte 5 kept them supported.

How is this different from the official Svelte playground?

The official REPL at svelte.dev is excellent and deliberately narrow — it is built to demonstrate the language. This keeps the same instant compile but adds a real file tree, npm packages, Git and a terminal, so an experiment can become a project without an export step.

Do runes work in .svelte.ts files?

Yes, and it is one of the more useful things about Svelte 5. Declare $state in a .svelte.ts module, export it, and import it anywhere — shared reactive state without a store and without a subscription to manage.

Does SvelteKit work here?

No, and that is a real limit rather than an omission. SvelteKit's routing, load functions and form actions run on a Node server, and there is no Node process in a browser tab. Components you build here move into a SvelteKit project unchanged, because the component layer is the same.

Are scoped styles really scoped?

Yes, with the same per-component attribute the compiler adds locally. Two components can each define .card with no collision, and there is no naming convention to maintain or configuration to enable it.

Do transitions and animations work?

Yes. svelte/transition and svelte/motion are part of the framework rather than an add-on, so fade, fly, slide, spring and tween are available with no install.

Can I use TypeScript?

Yes. <script lang="ts"> strips annotations during compilation, and $props() gives typed props with inference. There is no separate type-check pass blocking the loop, which is the same trade a local dev server makes.

Can I install Svelte libraries from npm?

Yes. Anything shipping ES modules resolves through esm.sh and imports by name. Packages that assume a Node build step or SvelteKit's server APIs will not work, for the same reason SvelteKit itself does not.

Is this a good place to learn Svelte 5?

Yes, and runes are the reason. The gap between Svelte 4's implicit reactivity and Svelte 5's explicit runes is where most confusion lives, and an instant compile loop is the fastest way to see what $derived actually recomputes and when.

Do I need to install anything to use XCODX Studio?

No. XCODX Studio is a browser-based IDE — the editor, the compilers and the preview all run client-side. There is no download, no package manager to set up and no configuration file to write. Opening the editor is the whole setup step.

Where is my code stored?

In your own browser. Projects, file history and Git objects live in local storage on your device and are never uploaded to a server. That also means XCODX works offline: it is a Progressive Web App, so you can install it and keep coding with no connection.

Is XCODX Studio free?

Yes. The editor, the live preview, the 70+ language runtimes, npm installs, Git and the integrated terminal are all free to use.

Can I use XCODX on a tablet or Chromebook?

Yes. The editor is a responsive web app, so a Chromebook, an iPad or an Android tablet gets the same compilers and the same preview a laptop does — there is no desktop-only build, because there is no build to install at all. The layout adapts to the screen rather than shrinking a desktop UI into it.

Can I export a project or move it to my own machine?

Yes. Export the whole project as a zip with its folder structure intact and open it locally, or commit it and push. It is ordinary source on disk from that point on — no proprietary format and no lock-in, which is also why importing an existing repository from GitHub works the same way in reverse.