Pug support for React in two parts:
- VS Code IntelliSense inside
pug\...`` templates - Build/lint transforms for Babel, SWC, esbuild, and ESLint
For now, clone the monorepo and run the following commands from the repository root:
npm ci
npm run package:vsix
code --install-extension .tmp/vsix/vscode-react-pug-tsx.vsixOr, to build and install in one step:
npm ci
npm run install:vsixThis builds the VSIX from the monorepo into .tmp/vsix/, keeps a stable install path at .tmp/vsix/vscode-react-pug-tsx.vsix, and installs it locally into VS Code.
For embedded editor support inside style(...) blocks:
cssandscsswork with built-in VS Code supportstylrequires the VS Code extensionsysoev.language-stylussassrequires the VS Code extensionSyler.sass-indented, since built-in VS Code CSS support does not handle indented Sass syntax
TODO: publish startupjs.vscode-react-pug-tsx to the VS Code Marketplace.
After that, installation by extension id will also work:
code --install-extension startupjs.vscode-react-pug-tsxPublished package names:
@react-pug/react-pug-core@react-pug/typescript-plugin-react-pugvscode-react-pug-tsx@react-pug/babel-plugin-react-pug@react-pug/swc-plugin-react-pug@react-pug/esbuild-plugin-react-pug@react-pug/eslint-plugin-react-pug
// babel.config.js
module.exports = {
plugins: [
['@react-pug/babel-plugin-react-pug', {
tagFunction: 'pug',
sourceMaps: 'basic',
requirePugImport: false,
classShorthandProperty: 'auto',
classShorthandMerge: 'auto',
startupjsCssxjs: 'auto',
componentPathFromUppercaseClassShorthand: true
}]
]
}Babel source map modes:
sourceMaps: 'basic'(default) keeps Babel on the simple AST replacement path, replaces only matchedpugtagged-template expressions duringProgramtraversal, and produces coarse mappings for transformed Pug regions while leaving surrounding JS/TS mappings Babel-native.sourceMaps: 'detailed'enables granular mappings back into Pug content by using BabelparserOverrideplus an inline input source map. Use this when you care about devtools/debugger fidelity through later Babel transforms.
import { transformWithSwcReactPug } from '@react-pug/swc-plugin-react-pug'
const result = transformWithSwcReactPug(sourceCode, fileName, {
jsc: {
parser: { syntax: 'typescript', tsx: true },
transform: { react: { runtime: 'automatic' } }
},
sourceMaps: true
})import { build } from 'esbuild'
import { reactPugEsbuildPlugin } from '@react-pug/esbuild-plugin-react-pug'
await build({
entryPoints: ['src/index.tsx'],
bundle: true,
plugins: [reactPugEsbuildPlugin()],
sourcemap: true
})// eslint.config.js (flat config)
import reactPugPlugin from '@react-pug/eslint-plugin-react-pug'
export default [
{
files: ['**/*.{js,jsx,ts,tsx}'],
plugins: { 'react-pug': reactPugPlugin },
processor: 'react-pug/pug-react'
}
]pugReact.enabledpugReact.diagnostics.enabledpugReact.tagFunctionpugReact.requirePugImport:boolean(defaultfalse)pugReact.injectCssxjsTypes:never | auto | forcepugReact.classShorthandProperty:auto | className | class | styleNamepugReact.classShorthandMerge:auto | concatenate | classnamespugReact.componentPathFromUppercaseClassShorthand:boolean(defaulttrue)
Import handling:
- used
pugimports are removed automatically from transformed output and shadow documents - when
requirePugImportis enabled, using the configured tag without an explicit import is treated as an error - when a terminal
styleblock is used,pugmust be imported so the matchingcss/styl/sass/scsshelper can be resolved from the same module
Class shorthand behavior:
- default auto:
className+ string concatenation - auto with
startupjs/cssxjsmarker:styleName+ classnames-style array merge
npm ci
npm run typecheck
npm run build
npm run test:core
npm run test:ts-plugin
npm run test:vscode
npm testIf you are working in an environment with NODE_ENV=production, install dev dependencies explicitly:
npm ci --include=devUseful:
npm run test:vscode:example:screenshots
npm run vscode:fresh:example
npm run check:pug:example
npx @react-pug/check-types .
npx @react-pug/check-types src/App.tsx src/Button.tsxPug-aware CI type check for a target project (without VS Code UI):
npx @react-pug/check-types <project-dir>If you are using StartupJS, the same checker can be exposed as:
npx startupjs check@react-pug/react-pug-corefinds tagged templates and compiles Pug regions.- For editor tooling, the TS plugin builds a shadow document and remaps LS results.
- For build/lint tooling, compiler adapters transform source and remap diagnostics to original Pug ranges.
Terminal style blocks can be embedded at the end of a pug template:
pug`
.title Hello
style(lang='styl')
.title
color red
`Behavior:
styledefaults tocss- supported langs:
css,styl,sass,scss - the
styleblock must be the last top-level node in the template - its content is moved to the top of the immediate enclosing scope as
css```,styl, `sassorscss``` and keeps${...}` interpolations intact - target scope selection:
- nearest enclosing block scope
- expression-bodied arrow functions are rewritten so the helper call can be inserted before the returned expression
- single-line
if/else/ loop statement bodies are normalized into blocks when needed so the helper call can be inserted before the original statement Programscope inserts right after the last import or directive
- the helper import is added from the same module as the file's
pugimport unless it already exists
- tags/components
- attrs and spread attrs
- class/id shorthand
- interpolation:
#{},!{}, and${}(including nestedpug) - line expressions:
tag= expression - control flow:
if,else if,else,each,while,case/when - unbuffered code:
- ... - text nodes and
|piped text - terminal
styleblocks with embedded CSS/SCSS editor support, plus Stylus/Sass when the corresponding VS Code language extension is installed
- VS Code extension currently targets desktop extension host (not web extension host).
- During heavily malformed in-progress edits, temporary mapping can be approximate until syntax stabilizes.
- Babel
sourceMaps: 'basic'is compatibility-first and does not preserve fine-grained mappings within a transformed Pug region. Surrounding non-Pug JS/TS code keeps normal Babel mappings. UsesourceMaps: 'detailed'when you need granular Babel source maps inside Pug. - Embedded Stylus editor IntelliSense depends on the external VS Code Stylus extension being installed.
- Embedded Sass editor IntelliSense/highlighting depends on the VS Code extension
Syler.sass-indentedbeing installed. Built-in VS Code CSS support handlescssandscss, but not indentedsass.
Detailed design and package internals: