CLI toolkit for building, testing and maintaining Bitrix extensions
- TypeScript First — Native TypeScript support with automatic transpilation
- Build — Rollup-based bundler with Babel, PostCSS, and automatic
process.env.NODE_ENVreplacement - Test — Unit tests (Mocha + Chai) in real browsers via Playwright, and E2E tests
- Lint — ESLint integration for consistent code quality
- Scaffold — Generate new extensions with
chef create - Migrate — Convert Flow.js to TypeScript with
chef flow-to-ts - Diagnostics — Dependency analysis, bundle sizes, circular dependencies and unused extension detection
npm install -g @bitrix/chefInitialize build environment:
chef init buildCreate and build your first extension:
chef create my.extension
chef build my.extension| Command | Description |
|---|---|
chef build |
Build extensions (TypeScript, Babel, PostCSS) |
chef test |
Run unit and E2E tests (use unit/e2e/module subcommands to run separately) |
chef typecheck |
Check TypeScript types in extensions |
chef lint |
Lint extensions with ESLint |
chef diag |
Diagnostics: dependencies, bundle sizes, cycles, unused extensions |
chef baseline |
Check web feature availability for current browser targets |
chef create <name> |
Scaffold a new extension |
chef aliases |
Regenerate TypeScript path aliases |
chef init build |
Initialize TypeScript, aliases, and browserslist |
chef init tests |
Initialize test environment |
chef init hooks |
Install VCS hooks to auto-update aliases |
chef flow-to-ts |
Migrate Flow.js to TypeScript |
Create bundle.config.ts in your extension directory:
export default {
input: './src/my.extension.ts',
output: {
js: './dist/my.extension.bundle.js',
css: './dist/my.extension.bundle.css',
},
namespace: 'BX.MyExtension',
};| Option | Type | Description |
|---|---|---|
input |
string |
Entry point file (.ts, .js or .css) |
output |
string | {js?, css?} |
Output bundle path(s) |
namespace |
string |
Global namespace for exports |
concat |
{js?: string[], css?: string[]} |
Concatenate files in specified order |
targets |
string | string[] |
Browser targets for transpilation |
sourceMaps |
boolean |
Generate source maps |
minification |
boolean | object |
Terser minification options |
treeshake |
boolean |
Remove unused code (default: true) |
plugins |
Plugin[] |
Custom Rollup plugins |
resolveNodeModules |
boolean |
Resolve dependencies from node_modules |
babel |
boolean |
Enable/disable Babel (default: true) |
transformClasses |
boolean | string[] |
Transpile classes — all (true) or by name |
rebuild |
string[] |
Extensions to rebuild after building the current one |
emitDeclaration |
boolean |
Generate .d.ts with namespace declarations (default: true) |
safeNamespaces |
boolean |
Safe access to dependency namespaces via optional chaining |
standalone |
boolean | object |
Standalone build with inlined dependencies |
cssImages |
object |
CSS image processing (type, maxSize, absolutePaths) |
baseline |
boolean |
Check web feature availability during build (default: true) |
JavaScript configuration (
bundle.config.js) is also supported.
A chef.config.ts file in the project root sets rules for all extensions:
export default {
deny: {
sfc: true, // block Vue SFC
exportDefault: true, // block export default
standalone: {
severity: 'warning', // or just warn
message: 'Standalone is not recommended',
},
},
defaults: { targets: 'last 2 versions' },
enforce: { sourceMaps: false },
};- deny — block options (
errorstops the build,warningshows a warning) - defaults — default values (can be overridden in
bundle.config) - enforce — forced values (cannot be overridden)
Chef uses browserslist to determine target browsers for Babel transpilation and CSS autoprefixing.
By default, Chef targets baseline widely available — browsers with widely available support for modern web features.
- If
targetsis specified inbundle.config.ts, Chef uses it directly - Otherwise, Chef looks for a
.browserslistrcfile up the directory tree - If no file is found, the default
baseline widely availableis used
Specify targets directly in the config:
export default {
// ...
targets: ['last 2 versions', 'not dead'],
};Or create a .browserslistrc file in the project root (use chef init build to generate one):
baseline widely available
local/js/vendor/extension/
├── bundle.config.ts # Build configuration
├── config.php # Bitrix extension config
├── src/
│ └── extension.ts # Entry point (named after extension)
├── dist/
│ ├── extension.bundle.js # Compiled bundle
│ ├── extension.bundle.d.ts # Type declarations (TypeScript)
│ └── extension.bundle.css # Compiled styles
└── test/
├── unit/ # Unit tests (Mocha + Chai)
│ └── example.test.ts
└── e2e/ # E2E tests (Playwright)
└── example.spec.ts
TypeScript configuration (tsconfig.json) is placed in the project root and shared across all extensions. Use chef init build to set it up.
JavaScript extensions (
.jsentry points) are also supported.
Initialize build environment for your project:
chef init buildThis command:
- Scans all extensions in the project
- Generates
aliases.tsconfig.jsonwith path aliases for every extension - Creates
tsconfig.jsonwith recommended settings - Creates
.browserslistrcwith recommended browser targets
After initialization, you can import extensions by name:
import { Loc, Tag } from 'main.core';
import { Button } from 'ui.buttons';aliases.tsconfig.json — auto-generated path mappings:
{
"compilerOptions": {
"baseUrl": "/path/to/project",
"types": ["./bitrix/js/ui/dev/src/ui.dev.ts"],
"paths": {
"main.core": ["./bitrix/js/main/core/src"],
"ui.buttons": ["./local/js/ui/buttons/src"]
}
}
}tsconfig.json — main config extending aliases:
{
"extends": "./aliases.tsconfig.json",
"compilerOptions": {
"module": "ESNext",
"target": "ESNext",
"moduleResolution": "bundler",
"strict": true
}
}If
tsconfig.jsonalready exists, the command will ask whether to overwrite it. You can manually add"extends": "./aliases.tsconfig.json"to your existing config.
To run unit and E2E tests you need to initialize the test environment first:
chef init testsThis creates two files in the project root:
| File | Description |
|---|---|
playwright.config.ts |
Playwright config for running unit and E2E tests in browser |
.env.test |
Credentials for automatic authentication during tests |
Fill in your local Bitrix installation credentials:
BASE_URL=http://localhost
LOGIN=admin
PASSWORD=your_password| Variable | Description |
|---|---|
BASE_URL |
URL of your local Bitrix installation |
LOGIN |
Test user login |
PASSWORD |
Test user password |
Security: Never commit
.env.testto version control — it contains sensitive credentials.
npx playwright installchef test main.core # Test specific extension
chef test ui.* --headed # Run with visible browser
chef test main.core -w # Watch mode
chef test --grep "should render" # Filter by test name
chef test main.core --debug # Open browser with DevTools and sourcemaps
chef test main.core --project chromium # Run in specific browser only
chef test module crm # Module-level scenario tests (several extensions)
chef test e2e ui.buttons --update-snapshots # Playwright options go to the runner as-isPlace tests in the extension's test/ directory:
my.extension/
└── test/
├── unit/ # Unit tests (Mocha + Chai, run in browser)
│ └── example.test.ts
└── e2e/ # E2E tests (Playwright)
└── example.spec.ts
Unit tests run inside a real browser via Playwright — Mocha and Chai are available globally. E2E tests use the standard Playwright Test API.
chef build [extensions...] [options]
Arguments:
extensions Extension names or glob patterns (e.g. main.core ui.bbcode.*)
Options:
-w, --watch Watch for changes and rebuild
-p, --path <path> Build specific directory
-v, --verbose Show detailed build logs
-f, --force Skip safety checks and force rebuild
Examples:
chef build main.core ui.buttons # Build specific extensions
chef build main.core -w # Build and watch for changes
chef build ui.bbcode.* # Build direct children matching pattern
chef build im.v2.** # Build all nested extensions
chef build ui.* -w # Build and watch
chef build # Build all extensions in current directory
Note: In zsh, escape glob patterns to prevent shell expansion: chef build ui.\*chef test [extensions...] [options] # unit + e2e
chef test unit [extensions...] [file?] # unit only
chef test e2e [extensions...] [file?] # e2e only
chef test module [modules...] [options] # module-level scenario tests
Arguments:
extensions Extension names or glob patterns (e.g. main.core ui.bbcode.*)
modules module only — module names (defaults to the current directory's module)
file unit/e2e only — test file name (e.g. dom.test.ts)
Options:
-w, --watch Watch for changes and rerun tests
-p, --path <path> Test specific directory
--headed Run browser tests in headed mode
--debug Open browser with DevTools and sourcemaps for debugging
--grep <pattern> Run only tests matching the pattern
--project <names> Run tests in specific browsers (chromium, firefox, webkit)
Any option chef does not own is forwarded to the Playwright runner (e2e only) —
see `chef test e2e --help` for the common ones.
Examples:
chef test main.core ui.buttons # Test specific extensions
chef test unit main.core # Unit tests only
chef test unit main.core ./render-tag.test.ts # Unit tests, specific file
chef test e2e ui.buttons # E2E tests only
chef test e2e ui.buttons ./render-buttons.spec.ts # E2E tests, specific file
chef test ui.* --headed # Direct children, with visible browser
chef test im.v2.** # All nested extensions
chef test main.core -w # Test and watch for changes
chef test main.core --debug # Debug with DevTools and sourcemaps
chef test main.core --project chromium firefox # Run in specific browsers
chef test e2e ui.buttons --update-snapshots # Playwright options go to the runner- Node.js >= 22
- Bitrix project or module source directory
Made for Bitrix developers