web/pug
Online Pug Editor Where the .pug File Is the Page
Write Pug the way a server-rendered project does — index.pug as the entry point, layouts extended, partials included, locals in a JSON file — and see the page itself rather than the markup it produced.
extends /layouts/base.pug
include ./partials/_card
block content
header.hero
h1.hero__title= title
p.hero__sub= tagline
each feature in features
+card(feature.name, feature.tone)
01 platform
The .pug file is the page, not a step before it
Most Pug tools online are converters: paste in, copy HTML out, then go and put it somewhere. That is not what this is, and the difference changes how you work.
-
index.pugIS the entry pointThere is no
index.htmlin the project and nothing writes one. XCODX compiles the template and serves the result at that route, so the file you are editing is the file being requested. -
No build step, and nothing to copy
No watcher to start, no output directory to check, no step between saving and seeing. The compile happens on render, in your browser, on every load.
-
Which means the project stays Pug
A converter forces you to keep two copies — the template you edit and the HTML you pasted. Here there is one, and it is the source, so nothing can drift out of step.
-
It is how a server-rendered project actually works
Express with Pug, or Django with its templates, does exactly this: the template is the route. Working the same way means what you learn transfers rather than being a browser-only habit.
02 deep dive
Data comes from a file, and editing it recompiles the page
A template with hard-coded strings is a mock-up. Pug earns its place when data arrives from outside it, and here that is an ordinary JSON file in the project.
pug.locals.json is the data. Everything in it is in scope: #{version}, = title, each feature in features. Edit the JSON and the page that read it recompiles.
The compiler records what each template read. A change to a layout, a partial or the locals invalidates exactly the pages that depend on it — not the whole project, and not nothing.
So partials behave like components. Edit _card.pug and every page including it updates. That is the dependency graph a build tool gives you, without the build tool.
Expressions are ordinary JavaScript. price.toFixed(2), items.filter(...), ternaries and template literals all work inside interpolation, because Pug compiles to a function rather than to a string.
- data
- pug.locals.json
- tracked
- every file a template read
- invalidates
- only dependent pages
- expressions
- real JavaScript
{
"title": "Pug on XCODX",
"version": "6.1.0",
"features": [
{ "name": "extends", "tone": "cyan", "breaking": false },
{ "name": "locals", "tone": "pink", "breaking": true }
]
}
03 pipeline
How extends and include find their files
Two different resolution rules, and knowing which is which saves the most common Pug afternoon.
-
extends from the project root
extends /layouts/base.pugstarts at the root of the project, so a layout referenced from three different depths is written the same way in all three. -
include relative to the file
include ./partials/_cardresolves from the template doing the including. The leading./is what makes that explicit rather than ambiguous. -
Mixins travel with the include
Including a file brings its
mixindefinitions into scope, which is why a partial of mixins is the usual way to build a component library in Pug. -
Blocks fill downward
A layout declares
block content; the page extending it fills, prepends or appends. Nothing is pasted sideways, so composition stays readable at depth.
04 features
Everything the Pug language gives you
The full language, compiled client-side on every render. Anything needing a Node process at build time is out of scope, and the FAQ says which.
-
Mixins with arguments and blocks
mixin card(name, tone),+card(...), default arguments and block content — the component model Pug is actually used for. -
extends, block and include
Template inheritance across a real folder tree, with
block appendandblock prependas well as plain replacement. -
Iteration and conditionals
each,while,if,unless,caseandelse, pluseach … elsefor the empty case. -
Attributes and shorthand
.class,#id,&attributes, boolean attributes anda(href=url)all behave as documented. -
Escaping you can reason about
=escapes,!=deliberately does not. That default is what stops interpolated data becoming an injection by accident. -
Stylesheets and scripts alongside
style.cssand any JavaScript in the project are linked from the layout and served with the page, exactly as they would be from a server.
05 workflow
Watching a dependency invalidate
One real sequence. The point is which files recompile and which do not.
- GET / → index.pug
- read layouts/base.pug, partials/_card.pug, pug.locals.json
- compiled · served as HTML
- edit → partials/_card.pug
- invalidated: index.pug (read _card.pug)
- recompiled · preview updated
-
The graph is recorded, not guessed
Every file a template reads is noted during the compile, so invalidation is exact rather than a blunt rebuild of everything.
-
Editing the locals is editing the page
pug.locals.jsonis a dependency like any other, which is why changing a value there updates the render immediately. -
Nothing to restart
There is no watcher process and no dev server holding stale state — the next request compiles against what is on disk now.
06 ecosystem
A template among other languages
A .pug file can sit beside a React component and a Python script; XCODX picks the right handling per file rather than per project.
07 languages
Every language the editor compiles
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
08 questions
Pug on XCODX — common questions
The questions that decide whether this fits your work.
Do I need to convert my Pug to HTML first?
No, and that is the main difference from most Pug tools online. index.pug is the entry point — XCODX compiles it and serves the result at that route. There is no index.html in the project and nothing writes one, so there is no second copy to keep in step.
Where does the data come from?
pug.locals.json in the project. Everything in it is in scope inside your templates, and because the compiler treats it as a dependency, editing a value there recompiles the pages that read it.
How do extends and include resolve?
extends starts at the project root — /layouts/base.pug — so a layout is written the same way from any depth. include resolves relative to the file doing the including, which is what the leading ./ makes explicit.
If I edit a partial, does every page rebuild?
No — only the pages that read it. The compiler records every file each template touched during its compile, so invalidation follows the real dependency graph rather than rebuilding the project.
Is Pug the same thing as Jade?
Yes. Jade was renamed Pug in 2016 after a trademark dispute, and the language is unchanged. Templates written as Jade compile here, which is why the old name still turns up in search.
Can I still get plain HTML out if I need it?
Yes — the compiled markup is what the preview serves, and exporting the project gives you the source with its structure intact. But for working in the browser you do not need to: the template is the page.
Does it work with a CSS framework?
Yes. The layout links stylesheets like any HTML document would, so plain CSS, SCSS compiled in the tab, or a utility framework from npm all apply to the rendered page.
Does this replace a Node build for Pug?
For authoring and previewing pages, yes — it does the same job an Express view engine does, in the browser. For a production pipeline that writes HTML to disk on deploy, no: that is a build step, and a browser tab has no Node process to run one.
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.
Nothing to install
Open the Pug editor
A real Pug page rendering in seconds — layouts extended, partials included, locals live — with no build step between the file and the page.
