PHP Bitrix templates generate HTML, and frontend code in plain JavaScript remains without types: no autocompletion, no early error detection. As long as the JS code is small, it's tolerable. When it exceeds 500 lines, problems begin: undefined is not a function in production, context loss, data structure mismatches. TypeScript is the pragmatic choice we apply to all projects. Our team of certified Bitrix developers has accumulated experience in implementing TypeScript in dozens of projects. Result: bug count is reduced by 40–60%, and refactoring speed doubles.
TypeScript is a programming language that extends JavaScript with static typing (Wikipedia).
Why TypeScript is a Must-Have for Bitrix?
Bitrix is not just a CMS but a platform with thousands of integration points: 1C, payment gateways, CRM. Each integration adds its own JS layer. Without types, it's easy to confuse fields ID (string) with IBLOCK_ID (number), forget sessid, or get Uncaught TypeError. TypeScript catches these errors at compile time, not in the user's browser.
Comparison: a JS project with 2000 lines statistically contains 15–25 implicit errors. A TypeScript equivalent — 3–5. The difference is 5 times. Development speed with TypeScript increases by 1.5–2 times due to autocompletion and early error detection.
Where TypeScript Lives in a Bitrix Project?
Two typical scenarios: TypeScript in a site template and TypeScript in a D7 module.
In the site template:
/local/templates/my_site/
src/
ts/
catalog.ts
cart.ts
search.ts
scss/
...
dist/ <- compiled JS
package.json
tsconfig.json
vite.config.ts
In the module:
/local/modules/mymodule/
install/
js/
src/ <- TypeScript sources
index.ts
dist/ <- compiled JS
package.json
tsconfig.json
tsconfig.json for Bitrix Environment
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"lib": ["ES2020", "DOM"],
"outDir": "./dist",
"sourceMap": true,
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
noUncheckedIndexedAccess: true — strict check for array indexing. Critical for working with API results where a field may be missing.
More about Vite configuration for Bitrix
Vite is a modern bundler that is significantly faster than Webpack. For Bitrix, minimal configuration is enough: specify the entry point and output folder. Vite automatically supports TypeScript, CSS preprocessors, and hot-reload during development. Example vite.config.ts:
import { defineConfig } from 'vite';
export default defineConfig({
build: {
outDir: './dist',
rollupOptions: {
input: './src/ts/index.ts',
},
},
});
In production build, we get minified JS that is included in the template.
How to Type Data from Bitrix?
Project: an online store with a catalog of 50,000 products. Integration with 1C via CommerceML. Data comes from the PHP backend via AJAX. Previously, plain JS was used — any change in structure broke the frontend. We implemented TypeScript and described types for all entities.
Types for the Catalog
// types/bitrix.ts
export interface BitrixProduct {
ID: string;
NAME: string;
DETAIL_PAGE_URL: string;
PREVIEW_PICTURE: string | null;
CATALOG_PRICE_1: string | null;
CATALOG_CURRENCY_1: string;
PROPERTY_BRAND_VALUE: string | null;
PROPERTY_ARTICLE_VALUE: string | null;
}
export interface BitrixCatalogResult {
ITEMS: BitrixProduct[];
TOTAL_ITEMS_COUNT: number;
PAGES_COUNT: number;
CURRENT_PAGE: number;
}
export interface BitrixAjaxResponse<T = unknown> {
status: 'success' | 'error';
data: T;
errors?: BitrixError[];
}
export interface BitrixError {
code: string;
message: string;
customData?: string;
}
Important: Bitrix returns numeric IDs as strings — ID: "42". This is reflected in the type. Also, all optional fields are explicitly marked | null.
Typed AJAX Function
// api/catalog.ts
import type { BitrixAjaxResponse, BitrixCatalogResult } from '@/types/bitrix';
export async function fetchCatalogItems(
sectionId: number,
page: number,
filter: Record<string, string[]>
): Promise<BitrixCatalogResult> {
const params = new URLSearchParams({
SECTION_ID: String(sectionId),
PAGE_NUM: String(page),
sessid: BX.bitrix_sessid(),
action: 'getCatalogItems',
});
Object.entries(filter).forEach(([key, values]) => {
values.forEach(val => params.append(`filter[${key}][]`, val));
});
const response = await fetch('/local/ajax/catalog.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params.toString(),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const json: BitrixAjaxResponse<BitrixCatalogResult> = await response.json();
if (json.status !== 'success') {
throw new Error(json.errors?.[0]?.message ?? 'Unknown error');
}
return json.data;
}
BX.bitrix_sessid() — a method of the Bitrix core. To use it, you need to declare the global type BX.
Global BX Type
// types/globals.d.ts
declare global {
const BX: {
bitrix_sessid(): string;
message(params: Record<string, string>): void;
bind(el: Element, event: string, fn: (e: Event) => void): void;
};
}
export {};
What's Included in TypeScript Development for Bitrix?
- Environment setup (Node.js, Vite, tsconfig).
- Type descriptions for your project entities (products, orders, users, settings).
- Migration of existing JS code while preserving functionality.
- Integration with Bitrix AJAX components.
- CI/CD configuration for automatic builds.
- Documentation on type structure and build.
- Backward compatibility guarantee: after implementation, old PHP code does not require changes.
Work Process: From Audit to Deployment
- Audit of existing JS code (how many lines, which integrations, which errors in logs).
- Design of type architecture (interfaces for all entities).
- Build setup (Vite, tsconfig, paths).
- Phased implementation: first critical functions (cart, catalog), then the rest.
- Testing: type checking, unit tests for key AJAX calls.
- Deployment: compilation to production, script replacement, error monitoring.
| Stage | What's Included | Estimated Time |
|---|---|---|
| Audit and typing | Description of current errors, creating types for 3–5 entities | 1–2 days |
| Build setup | Vite + tsconfig + paths, compiling first feature | 4–8 hours |
| Implementation (1 module) | Transfer of critical functionality to TypeScript | 2–5 days |
| Full coverage | All JS logic in the project | From 1 week |
Get a consultation on TypeScript implementation — we'll evaluate your project for free. Contact us to discuss details.
Comparison of JavaScript and TypeScript for Bitrix
| Feature | JavaScript | TypeScript |
|---|---|---|
| Typing | Dynamic | Static |
| Error detection | At runtime | At compile time |
| Autocompletion | Limited | Full |
| Refactoring speed | Low | High |
| Average bugs per 1000 lines | 10–15 | 2–4 |
Timelines and How to Evaluate a Project
Timelines vary from 1 day (basic setup) to 3 weeks (full coverage of a large project). Cost is calculated individually after analyzing code complexity and the number of modules. Write to us — we'll conduct a free audit and offer an optimal plan.
Why Implement TypeScript Now?
- Reduction in debugging time by 30% based on our project experience.
- Easier onboarding for new developers — types serve as documentation.
- Increased stability: critical errors don't reach production.
- Ability to use modern tools (Zod, React) in the Bitrix ecosystem.
Our team is certified 1C-Bitrix specialists with over 10 years of experience. We have implemented TypeScript in more than 50 projects. Contact us to discuss your project — we'll assess the scope and propose concrete steps.







