3 months ago
I'm experiencing a critical deployment issue where my Node.js/TypeScript application builds successfully locally but fails on Railway with TypeScript module resolution errors.
Environment:
Platform: Railway
Runtime: Node.js 18
Build Method: Dockerfile
Framework: Express.js with TypeScript
Build Tool: ts-node
Issue Summary: My application works perfectly in local development (Windows) and local Docker, but consistently fails on Railway with "Cannot find module" errors for controller files that definitely exist.
Error Details:
TSError: ⨯ Unable to compile TypeScript:
src/routes/auth.ts(3,28): error TS2307: Cannot find module '../controllers/authController' or its corresponding type declarations.
src/routes/masterDataRoutes.ts(9,8): error TS2307: Cannot find module '../controllers/masterDataController' or its corresponding type declarations.
File Structure Confirmed Locally:
src/
├── controllers/
│ ├── authController.ts ✓ (exists)
│ ├── masterDataController.ts ✓ (exists)
│ └── [other controllers]
├── routes/
│ ├── auth.ts (imports '../controllers/authController')
│ └── masterDataRoutes.ts (imports '../controllers/masterDataController')
Import Statements:
// src/routes/auth.ts
import authController from '../controllers/authController';
// src/routes/masterDataRoutes.ts
import { getCategories } from '../controllers/masterDataController';
What Works:
Local development (
npm run dev
)Local Docker build and run
TypeScript compilation locally (
npx tsc
)All file paths and case sensitivity verified
What Fails:
Railway deployment with ts-node runtime compilation
Only specific controller imports (not all files)
Configuration Files:
package.json:
{
"scripts": {
"start": "ts-node src/index.ts",
"build": "echo 'Skipping TypeScript compilation - using ts-node'"
},
"dependencies": {
"ts-node": "^10.9.2",
"typescript": "^5.8.3"
}
}
tsconfig.json:
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
railway.toml:
[build]
builder = "DOCKERFILE"
Troubleshooting Attempted:
Verified file case sensitivity (all lowercase)
Tested different import syntaxes (named vs default)
Confirmed tsconfig.json module resolution settings
Tried both individual and namespace imports
Verified Railway is using Dockerfile build method
Tested with simplified controller files (no circular dependencies)
Questions:
Are there known issues with ts-node module resolution in Railway's container environment?
Could this be related to file deployment or volume mounting during build?
Are there Railway-specific TypeScript or Node.js path resolution quirks?
Expected Behavior: The application should start successfully on Railway, just as it does locally.
Actual Behavior: Application crashes during startup with TypeScript module resolution errors for files that exist.
Request: Please help identify why Railway's ts-node environment cannot resolve these controller modules, despite them working perfectly in identical local Docker environments.
2 Replies
3 months ago
Hey there! We've found the following might help you get unblocked faster:
If you find the answer from one of these, please let us know by solving the thread!
2 months ago
Quick Fixes:
Method 1: Check your Dockerfile
Ensure your Dockerfile properly copies all files:
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
CMD ["npm", "start"]
Method 2: Switch from ts-node to tsc compilation
Replace your current approach:
// package.json
{
"scripts": {
"start": "node dist/index.js",
"build": "tsc"
}
}
Make sure you have build command in docker file:
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build # ✅ Build
CMD ["npm", "start"] # ✅ Star.t
Method 3: Add tsconfig-paths for ts-node (if keeping ts-node)
npm install --save-dev tsconfig-paths
Update tsconfig.json:
{
"ts-node": {
"require": ["tsconfig-paths/register"]
},
"compilerOptions": {
"moduleResolution": "node",
"baseUrl": "./src",
...
}
}
Why this happens:
Railway uses Linux containers (case-sensitive) vs your Windows dev environment
ts-node has module resolution issues in containerized environments
Working directory differences between local Docker and Railway
Best solution:
Pre-compile with tsc instead of runtime compilation with ts-node. This is more reliable for production deployments and what most Railway users end up doing.
The compilation approach eliminates module resolution issues entirely and matches Railway's recommended deployment patterns.