a year 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
a year ago
Hey there! We've found the following might help you get unblocked faster:
- 🧵 Railway ignore node version value
- 📚 Deploy an Astro App
- 🧵 cant build react project, need more updated node version
If you find the answer from one of these, please let us know by solving the thread!
a year 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.tMethod 3: Add tsconfig-paths for ts-node (if keeping ts-node)
npm install --save-dev tsconfig-pathsUpdate 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.