rscute: In-memory TypeScript Bundler and Executor
rscute is an in-memory TypeScript bundler and executor, leveraging `@swc/core` for high-performance AST transformation and compilation. Currently at stable version 1.2.2, it exhibits an active release cadence with frequent updates. Its core functionality involves intercepting Node.js `require` calls, recursively resolving TypeScript and JavaScript dependencies, and evaluating them as a single, flattened bundle entirely within memory. Key differentiators include its transparent runtime execution capabilities for TypeScript files, a dedicated API for in-memory bundling without execution, and automatic symbol mangling to prevent name collisions in the flattened module scope. It supports various entry points, including a CLI, a Node.js `-r` flag hook, and dedicated programmatic APIs for code execution in a sandboxed VM context or for bundling to a string.
Common errors
-
Error: Cannot find module 'some-module' from 'path/to/file.ts'
cause `rscute` could not resolve an imported module's path, possibly due to incorrect `baseUrl` settings (especially after v1.2.2), missing `node_modules` entry, or incorrect relative paths.fixVerify the module path is correct relative to the importing file or `filePath` option. Ensure dependencies are installed. If using `baseUrl`, review your `tsconfig.json` and module resolution after `rscute@1.2.2`. -
TypeError: register is not a function
cause Attempting to use `import { register } from 'rscute/register'` in an ESM context, or trying to access `register` without destructuring in CommonJS.fixFor CommonJS, ensure `const { register } = require('rscute/register');` is used. The `register` API is primarily a CommonJS hook. -
SyntaxError: Cannot use import statement outside a module
cause Running a file with `import` statements (e.g., `rscute/vm` or `rscute/bundle` APIs) in a Node.js environment configured for CommonJS.fixEnsure your Node.js project is configured for ESM by setting `"type": "module"` in `package.json` or by using `.mjs` file extensions for files containing `import` statements. -
ReferenceError: require is not defined
cause Attempting to use `require()` within an ESM module context (e.g., a file with `import`s or a `.mjs` file).fixReplace `require()` calls with `import` statements where appropriate, or ensure you are in a CommonJS context if `require()` is necessary. -
SWC compilation error: [specific SWC error message]
cause An error occurred during the SWC transformation process, often due to invalid TypeScript syntax, unsupported language features, or configuration issues.fixReview the specific SWC error message for details. Check your TypeScript code for syntax errors. Ensure `@swc/core` is up-to-date and compatible with your Node.js version.
Warnings
- breaking Version 1.2.0 introduced a major architectural refactoring, cleanly separating the core AST engine from execution environments. While new APIs (`rscute/bundle`) were added, this change may affect applications relying on older undocumented programmatic interfaces or internal structures.
- breaking Version 1.0.0 replaced regular expression processing with full AST parsing. While this generally improves accuracy and robustness, it might introduce subtle breaking changes for projects with highly specific or unusual TypeScript syntax that was implicitly handled (or mishandled) by the previous regex-based approach.
- gotcha When using `pnpm` as your package manager, direct `npx rscute` commands may not work as expected due to how `npx` resolves packages with `pnpm`.
- breaking Version 1.2.2 removed `baseUrl` logic for TS6. This change might impact projects that rely on specific `baseUrl` configurations within their `tsconfig.json` for module resolution, potentially leading to "Cannot find module" errors.
- gotcha `rscute` provides both CommonJS (`rscute/register`) and ESM-focused (`rscute/vm`, `rscute/bundle`) APIs. Mixing `require()` for ESM-only modules or `import` for CommonJS-only modules will lead to errors.
- breaking Version 1.1.5 included a "supply-chain security update" and enabled npm provenance. While specific details were not provided, users on older versions should upgrade to `>=1.1.5` to ensure they receive critical security patches related to the package's integrity.
Install
-
npm install rscute -
yarn add rscute -
pnpm add rscute
Imports
- register
import { register } from 'rscute/register';const { register } = require('rscute/register'); - execute
const { execute } = require('rscute/vm');import { execute } from 'rscute/vm'; - bundle
const { bundle } = require('rscute/bundle');import { bundle } from 'rscute/bundle';
Quickstart
import { bundle } from 'rscute/bundle';
import { execute } from 'rscute/vm';
import path from 'path';
import fs from 'fs';
// Create a temporary script.ts for the example
const tempScriptContent = `
export const getMessage = (name: string): string => {
return \`Hello, \${name} from bundled code!\`;
};
export const someValue = 42;
`;
const tempScriptPath = path.resolve(__dirname, 'temp-script.ts');
fs.writeFileSync(tempScriptPath, tempScriptContent);
try {
// 1. Bundle the TypeScript file into a single JavaScript string
console.log('Bundling temp-script.ts...');
const bundledCode = bundle(tempScriptPath);
console.log('\n--- Bundled Code (truncated) ---');
console.log(bundledCode.substring(0, 200) + '...');
// 2. Execute the bundled code in a VM context
console.log('\nExecuting bundled code in VM...');
const moduleExports = execute(bundledCode);
// 3. Use the exports from the executed code
if (moduleExports && typeof moduleExports.getMessage === 'function') {
console.log(`Result from executed bundle: ${moduleExports.getMessage('rscute user')}`);
console.log(`Exported value: ${moduleExports.someValue}`);
} else {
console.error('Failed to get expected exports from bundled code.');
}
} catch (error) {
console.error('An error occurred:', error);
} finally {
// Clean up the temporary file
fs.unlinkSync(tempScriptPath);
}