🎯

allowjs-mixing

🎯Skill

from marius-townhouse/effective-typescript-skills

VibeIndex|
What it does

Enables gradual TypeScript migration by mixing JavaScript and TypeScript files in the same project, allowing incremental conversion of codebases.

πŸ“¦

Part of

marius-townhouse/effective-typescript-skills(83 items)

allowjs-mixing

Installation

Quick InstallInstall with npx
npx skills add marius-townhouse/effective-typescript-skills --all
Quick InstallInstall with npx
npx skills add marius-townhouse/effective-typescript-skills -s prefer-unknown-over-any exhaustiveness-checking
Quick InstallInstall with npx
npx skills add marius-townhouse/effective-typescript-skills -a opencode claude-code
Quick InstallInstall with npx
npx skills add marius-townhouse/effective-typescript-skills -l
git cloneClone repository
git clone https://github.com/marius-townhouse/effective-typescript-skills.git
πŸ“– Extracted from docs: marius-townhouse/effective-typescript-skills
1Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

Use when migrating JavaScript to TypeScript. Use when gradually adopting TypeScript. Use when working with mixed codebases. Use when converting large projects. Use when teams are learning TypeScript.

Overview

# Use allowJs to Mix TypeScript and JavaScript

Overview

Migrating a large JavaScript codebase to TypeScript doesn't have to be all-or-nothing. The allowJs compiler option lets you gradually adopt TypeScript by mixing .ts and .js files in the same project. This enables incremental migration, allowing teams to convert files one at a time while maintaining a working codebase.

This approach is essential for large migrations where a big-bang rewrite isn't feasible.

When to Use This Skill

  • Migrating JavaScript projects to TypeScript
  • Gradually adopting TypeScript in a JS codebase
  • Working with mixed TypeScript/JavaScript teams
  • Converting large existing projects
  • Teams still learning TypeScript

The Iron Rule

Use allowJs to enable incremental migration. Convert files module by module, starting from leaf modules and working up the dependency graph.

Detection

Watch for migration challenges:

```

// Can't migrate because:

  • 1000+ JavaScript files
  • Team still learning TypeScript
  • Can't stop feature development
  • Risk of breaking changes

```

Enabling allowJs

```json

// tsconfig.json

{

"compilerOptions": {

"allowJs": true, // Allow JavaScript files

"checkJs": false, // Don't type check JS (optional)

"outDir": "./dist",

"strict": true

},

"include": ["src/*/"]

}

```

Migration Strategy

```

Phase 1: Enable allowJs

- Add tsconfig.json with allowJs: true

- Rename one file to .ts as proof of concept

- Ensure build still works

Phase 2: Convert leaf modules

- Start with files that have no dependencies

- Utilities, helpers, constants

- Low risk, easy wins

Phase 3: Work up dependency graph

- Convert files that only depend on converted files

- Gradually move toward entry points

Phase 4: Convert entry points last

- Main files, app entry points

- Most complex, most dependencies

```

Converting a File

```javascript

// utils.js (before)

export function formatDate(date) {

return date.toISOString().split('T')[0];

}

export const PI = 3.14159;

```

```typescript

// utils.ts (after)

export function formatDate(date: Date): string {

return date.toISOString().split('T')[0];

}

export const PI = 3.14159;

```

Importing Between JS and TS

```typescript

// app.ts - TypeScript importing JavaScript

import { formatDate } from './utils.js'; // .js extension

// TypeScript trusts the JS (with checkJs: false)

// With types for JS module

declare module './utils.js' {

export function formatDate(date: Date): string;

export const PI: number;

}

```

```javascript

// legacy.js - JavaScript importing TypeScript

import { User } from './types.ts'; // Works with allowJs

// JS doesn't get type checking, but can import TS

```

Adding Types to JavaScript

```javascript

// @ts-check - Enable type checking for this file

/**

* @param {string} name

* @param {number} age

* @returns {string}

*/

function greet(name, age) {

return Hello ${name}, you are ${age};

}

/* @type {string[]} /

const names = ['Alice', 'Bob'];

/* @typedef {{ x: number, y: number }} Point /

```

Migration Checklist

```typescript

// 1. Set up tsconfig.json with allowJs

{

"compilerOptions": {

"allowJs": true,

"checkJs": false, // Enable later for stricter checking

"outDir": "./dist",

"strict": true,

"esModuleInterop": true

}

}

// 2. Start with simple files

// - No dependencies

// - Pure functions

// - Well-tested

// 3. Add types gradually

// - Start with any if needed

// - Refine over time

// 4. Enable strict mode checks incrementally

// - noImplicitAny

// - strictNullChecks

// - strictFunctionTypes

```

Pressure Resistance Protocol

When migrating:

  1. Enable allowJs first: Get the infrastructure working
  2. Start small: Convert one file, ensure build works
  3. Prioritize leaf modules: Fewer dependencies = easier
  4. Use any initially: Can refine types later
  5. Track progress: Celebrate small wins

Red Flags

| Anti-Pattern | Problem | Solution |

|--------------|---------|----------|

| Big-bang rewrite | Too risky, takes too long | Incremental with allowJs |

| Converting entry points first | Too many dependencies | Start with leaves |

| No tsconfig.json | Can't control compilation | Set up properly |

| Abandoning midway | Wasted effort | Track and celebrate progress |

Common Rationalizations

"We need to convert everything at once"

Reality: Incremental migration with allowJs is safer and more practical for large codebases.

"Mixed JS/TS is confusing"

Reality: It's temporary and manageable. Clear migration plan keeps it organized.

"We'll just keep using JS"

Reality: TypeScript's benefits compound over time. Start small and grow.

Quick Reference

| Step | Action | Timeline |

|------|--------|----------|

| 1 | Add tsconfig with allowJs | Day 1 |

| 2 | Convert 1-2 utility files | Week 1 |

| 3 | Convert leaf modules | Weeks 2-4 |

| 4 | Work up dependency graph | Months 1-3 |

| 5 | Convert entry points | Months 3-6 |

| 6 | Remove allowJs (optional) | When done |

The Bottom Line

Use allowJs for incremental TypeScript adoption. Convert files gradually, starting from leaf modules. This makes large migrations manageable without stopping development.

Reference

  • Effective TypeScript, 2nd Edition by Dan Vanderkam
  • Item 81: Use allowJs to Mix TypeScript and JavaScript

More from this repository10

🎯
tsdoc-comments🎯Skill

Generates TypeScript documentation comments (TSDoc) to explain public APIs, complex types, and provide comprehensive code documentation with IDE tooltips.

🎯
async-over-callbacks🎯Skill

Transforms callback-based asynchronous code into clean, readable async/await patterns for better type flow and error handling.

🎯
type-safe-monkey-patching🎯Skill

Enables type-safe runtime extension of global objects and DOM elements in TypeScript without sacrificing type checking or using `as any`.

🎯
create-objects-all-at-once🎯Skill

Efficiently initializes multiple TypeScript objects simultaneously using concise object literal syntax and spread operators.

🎯
module-by-module-migration🎯Skill

Guides developers through systematic TypeScript module migration, breaking down complex refactoring into manageable, incremental steps.

🎯
ts-js-relationship🎯Skill

Explains TypeScript's relationship to JavaScript, highlighting how it adds static typing and catches errors before runtime while remaining fully compatible with JavaScript code.

🎯
code-gen-independent🎯Skill

Generates JavaScript code despite TypeScript type errors and demonstrates that TypeScript types are erased at runtime, requiring alternative type checking strategies.

🎯
context-type-inference🎯Skill

Helps restore precise type context when extracting values, preventing type inference errors through annotations, const assertions, and type preservation techniques.

🎯
precise-string-types🎯Skill

Enforces strict string type constraints and prevents unintended string type conversions in TypeScript projects.

🎯
type-display-attention🎯Skill

Displays and simplifies complex TypeScript types to improve IDE readability and developer experience.