A powerful Node.js runtime transformer that enables direct execution of TypeScript, JSX, TSX, and CSS files without requiring pre-compilation. Built with SWC for fast compilation and designed for seamless integration with Node.js module system.
📖 中文文档: 查看中文版 README
- Runtime TypeScript Compilation: Execute
.ts
and.tsx
files directly with SWC - Module Alias Support: Configure path aliases for cleaner imports
- Extensible Transformer System: Add custom transformers for additional file types
- Node.js Version Compatibility: Works with both Node.js <24 (polyfill) and >=24 (native hooks)
- Zero Build Step: No pre-compilation required, everything happens at runtime
- Fast Performance: Leverages SWC for speedy compilation
- TypeScript Support: Full TypeScript support with decorators and metadata
npm install rts.js
The easiest way to use RTS is with the register module:
# Run TypeScript files directly
node -r rts.js/register app.ts
# Or use in package.json scripts
{
"scripts": {
"start": "node -r rts.js/register src/index.ts",
"dev": "node -r rts.js/register src/dev.ts"
}
}
import { registerRTS } from 'rts.js';
// Register RTS hooks
const cleanup = registerRTS();
// Now you can import TypeScript files directly
import { MyComponent } from './components/MyComponent.tsx';
// Cleanup when done
cleanup();
import { registerRTS } from 'rts.js';
const cleanup = registerRTS({
alias: {
'@components': './src/components',
'@utils': ['./src/utils', './src/helpers'],
'@types': './src/types'
}
});
// Use aliases in your imports
import { Button } from '@components/Button';
import { formatDate } from '@utils/date';
import { registerRTS } from 'rts.js';
import type { TransformerHook } from 'rts.js';
// Create a custom CSS transformer
const CSSHook: TransformerHook = {
exts: ['.css'],
hook: (code: string) => {
// Transform CSS to JS module
return `export default ${JSON.stringify(code)};`;
}
};
const cleanup = registerRTS({
transformers: [CSSHook]
});
Registers RTS hooks with Node.js module system.
Parameters:
options
(optional): Configuration objectalias
: Module alias mappingtransformers
: Array of custom transformers
Returns: Cleanup function to deregister hooks
interface RTSOptions {
alias?: Record<string, string[] | string>;
transformers?: TransformerHook[];
}
interface TransformerHook {
exts: string[];
hook: (code: string, src: string) => string;
}
Aliases allow you to use shorter import paths that resolve to actual file paths:
const cleanup = registerRTS({
alias: {
'@components': './src/components',
'@utils': ['./src/utils', './src/helpers'],
'@types': './src/types'
}
});
Create custom transformers for additional file types:
const JSONHook: TransformerHook = {
exts: ['.json'],
hook: (code: string) => {
const data = JSON.parse(code);
return `module.exports = ${JSON.stringify(data)};`;
}
};
const cleanup = registerRTS({
transformers: [JSONHook]
});
RTS supports both older and newer Node.js versions:
- Node.js >=24: Uses native
Module.registerHooks
API - Node.js <24: Uses polyfill implementation with same functionality
// app.ts
import express from 'express';
import { registerRTS } from 'rts';
const cleanup = registerRTS({
alias: {
'@routes': './src/routes',
'@middleware': './src/middleware'
}
});
import { userRoutes } from '@routes/users';
import { authMiddleware } from '@middleware/auth';
const app = express();
app.use('/api/users', authMiddleware, userRoutes);
app.listen(3000, () => {
console.log('Server running on port 3000');
});
// Cleanup on process exit
process.on('SIGINT', () => {
cleanup();
process.exit(0);
});
// components/Button.tsx
import React from 'react';
interface ButtonProps {
children: React.ReactNode;
onClick?: () => void;
variant?: 'primary' | 'secondary';
}
export const Button: React.FC<ButtonProps> = ({
children,
onClick,
variant = 'primary'
}) => {
return (
<button
className={`btn btn-${variant}`}
onClick={onClick}
>
{children}
</button>
);
};
/* styles/button.css */
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
.btn-primary {
background-color: #007bff;
color: white;
}
.btn-secondary {
background-color: #6c757d;
color: white;
}
pnpm start
: Run the development serverpnpm test
: Run testspnpm test:watch
: Run tests in watch modepnpm test:coverage
: Run tests with coveragepnpm run lint
: Run lintingpnpm run lint:fix
: Fix linting issuespnpm run check
: Run type checkingpnpm run check:fix
: Fix type checking issuespnpm run format
: Format codepnpm run build
: Build the project (implement as needed)
This project uses Changesets for version management and releases.
Creating a release:
# 1. Create a changeset
pnpm changeset
# 2. Build and test
pnpm run build
pnpm test
# 3. Release
pnpm run release
Available release commands:
pnpm changeset
: Create a new changesetpnpm run release
: Full release processpnpm run release:dry-run
: Test release without making changespnpm run release:build
: Build and validatepnpm run release:test
: Run tests onlypnpm run release:tag
: Create git tag for current version
For detailed information, see the Release Guide.
RTS consists of several key components:
Handles module path resolution, caching, and alias mapping. Integrates with Node.js module system through hooks.
Transform source code from one format to another. Currently includes TypeScript transformer using SWC.
Provides Node.js version compatibility by using native APIs when available and polyfills for older versions.
Handles configuration loading, parsing, and merging.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the ISC License - see the LICENSE file for details.
- SWC for fast TypeScript compilation
- Node.js team for the module hooks API
- The TypeScript community for inspiration and feedback