Skip to main content

TypeScript 5.9.3 + Node.js 22.22.0 (Ubuntu 24.04) AMI Administrator Guide

1. Quick Start Information

Connection Methods:

  • Access the instance via SSH using the ubuntu user. Use sudo to run commands requiring root privileges. To switch to the root user, use sudo su - root.

Install Information:

  • OS: Ubuntu 24.04 LTS
  • Node.js version: 22.22.0 (via NodeSource official repository)
  • TypeScript version: 5.9.3
  • ts-node version: 10.9.2
  • npm version: 10.9.4
  • Node Install Directory: /usr/bin/node
  • Global npm Modules: /usr/lib/node_modules

Quick Verification Commands:

  • Check Node.js version: node -v
  • Check npm version: npm -v
  • Check TypeScript compiler version: tsc -v
  • Check ts-node version: ts-node -v
  • Verify Node.js location: which node

Development Tools Included:

  • Node.js: node (v22.22.0 LTS)
  • npm Package Manager: npm (v10.9.4)
  • TypeScript Compiler: tsc (v5.9.3)
  • TypeScript REPL/Runner: ts-node (v10.9.2)
  • Node.js Type Definitions: @types/node

Firewall Configuration:

  • Please allow SSH port 22.
  • For security, it is recommended to limit SSH access to trusted IPs only.

2. First Launch & Verification

Step 1: Connect to Your Instance

  1. Launch your instance in your cloud provider's console (e.g., AWS EC2)
  2. Ensure SSH port 22 is allowed in your security group
  3. Connect via SSH:
    ssh -i your-key.pem ubuntu@YOUR_PUBLIC_IP

Step 2: Verify Node.js Installation

Check the Node.js version:

node -v

Expected Output:

v22.22.0

Verify the installation path (must show system-wide installation):

which node

Expected Output:

/usr/bin/node

Step 3: Verify npm Installation

Check the npm version:

npm -v

Expected Output:

10.9.4

Step 4: Verify TypeScript Compiler

Check the TypeScript version:

tsc -v

Expected Output:

Version 5.9.3

Step 5: Verify ts-node

Check the ts-node version:

ts-node -v

Expected Output:

v10.9.2

Step 6: One-Command Verification

Run this command to verify all components at once:

echo "Node: $(node -v)"
echo "NPM: $(npm -v)"
echo "TSC: $(tsc -v)"
echo "TS-Node: $(ts-node -v)"

Expected Output:

Node: v22.22.0
NPM: 10.9.4
TSC: Version 5.9.3
TS-Node: v10.9.2

Step 7: Test TypeScript Compilation

Create a simple TypeScript file and test the compilation workflow:

# Create a test TypeScript file
echo 'let message: string = "Hello, TypeScript on Ubuntu!"; console.log(message);' > hello.ts

# Compile TypeScript to JavaScript
tsc hello.ts

# Run the compiled JavaScript
node hello.js

Expected Output:

Hello, TypeScript on Ubuntu!

How This Works:

  1. tsc hello.ts compiles the TypeScript file into JavaScript (creates hello.js)
  2. node hello.js executes the compiled JavaScript file
  3. The type annotation string is stripped during compilation (TypeScript is a compile-time type system)

Step 8: Test Direct TypeScript Execution

You can also execute TypeScript files directly using ts-node without manual compilation:

# Run TypeScript directly
ts-node hello.ts

Expected Output:

Hello, TypeScript on Ubuntu!

3. Architecture & Detailed Configuration

This AMI uses the NodeSource official repository for Node.js installation, ensuring you get the latest LTS version with long-term support and security updates. TypeScript and related tools are installed globally via npm, making them accessible to all users.

Installation Architecture:

[NodeSource Repository]

[Node.js 22.22.0] → /usr/bin/node

[npm 10.9.4] → /usr/bin/npm

[Global npm install -g]

├── TypeScript 5.9.3 → /usr/lib/node_modules/typescript
├── ts-node 10.9.2 → /usr/lib/node_modules/ts-node
└── @types/node → /usr/lib/node_modules/@types/node

[Symlinks in /usr/bin/]
├── /usr/bin/tsc → ../lib/node_modules/typescript/bin/tsc
└── /usr/bin/ts-node → ../lib/node_modules/ts-node/dist/bin.js

Key Design Decisions:

  1. System-Wide Installation: Node.js installed via apt package manager for easy updates and system integration
  2. NodeSource Repository: Official Node.js repository ensures we get v22 LTS instead of Ubuntu's outdated version
  3. Global npm Packages: TypeScript tools installed globally with sudo npm install -g for all users
  4. GPG Key Verification: NodeSource repository signed with GPG key for package authenticity

3.1. NodeSource Repository Configuration

File Location: /etc/apt/sources.list.d/nodesource.list

File Content:

deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main

How This Works:

  • signed-by=/etc/apt/keyrings/nodesource.gpg: Specifies the GPG key for package verification
  • node_22.x: Locks the repository to Node.js 22 LTS (prevents accidental upgrades to v23, v24, etc.)
  • nodistro: Distribution-agnostic repository (works across Ubuntu versions)

GPG Key Location: /etc/apt/keyrings/nodesource.gpg

This key file verifies that all packages downloaded from NodeSource are authentic and have not been tampered with.


3.2. Global npm Packages

Installation Directory: /usr/lib/node_modules/

Installed Packages:

  1. typescript (v5.9.3)

    • Compiler: /usr/lib/node_modules/typescript/bin/tsc
    • Type Checker: /usr/lib/node_modules/typescript/bin/tsserver
  2. ts-node (v10.9.2)

    • Runner: /usr/lib/node_modules/ts-node/dist/bin.js
    • Allows direct execution of .ts files without pre-compilation
  3. @types/node (latest)

    • Node.js API type definitions
    • Enables TypeScript IntelliSense for Node.js built-in modules (fs, http, path, etc.)

Binary Symlinks:

/usr/bin/tsc → /usr/lib/node_modules/typescript/bin/tsc
/usr/bin/ts-node → /usr/lib/node_modules/ts-node/dist/bin.js

These symlinks allow you to run tsc and ts-node from anywhere without specifying the full path.


4. How-To-Create: Reproduce This Environment

This section explains how this AMI was built, allowing you to reproduce the installation on any Ubuntu 24.04 system.

Step 1: Add NodeSource Official Repository

Purpose: Configure apt to download Node.js 22 LTS from NodeSource instead of Ubuntu's default repository.

# Install dependencies for repository management
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg

# Create keyrings directory
sudo mkdir -p /etc/apt/keyrings

# Download and import NodeSource GPG key
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg

# Create repository source file (lock to Node.js 22)
NODE_MAJOR=22
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list

How This Works:

  1. ca-certificates: Enables HTTPS connections for downloading packages
  2. curl: Downloads the NodeSource GPG key
  3. gpg --dearmor: Converts the ASCII-armored GPG key to binary format
  4. NODE_MAJOR=22: Sets the major version to 22 (LTS)
  5. tee: Writes the repository configuration to the sources list

Why NodeSource?

Ubuntu's default repository often provides outdated Node.js versions (e.g., v12 or v14). NodeSource maintains official repositories with the latest LTS releases, security patches, and performance improvements.

Step 2: Install Node.js

Purpose: Install Node.js 22.22.0 and npm from the newly added repository.

# Update package index with new repository
sudo apt-get update

# Install Node.js (includes npm)
sudo apt-get install -y nodejs

How This Works:

  • apt-get update: Fetches package lists from all configured repositories (including NodeSource)
  • apt-get install -y nodejs: Installs the latest Node.js 22 package
  • The package automatically installs:
    • /usr/bin/node: Node.js runtime
    • /usr/bin/npm: Node Package Manager
    • /usr/bin/npx: npm package executor

Verification:

which node  # /usr/bin/node
node -v # v22.22.0
npm -v # 10.9.4

Step 3: Install TypeScript Globally

Purpose: Install TypeScript compiler, ts-node runner, and Node.js type definitions globally for all users.

# Install all TypeScript tools globally
sudo npm install -g typescript ts-node @types/node

How This Works:

  • npm install -g: Installs packages globally (system-wide, not project-specific)
  • sudo: Required because global packages install to /usr/lib/node_modules/ (protected directory)
  • typescript: Provides the tsc compiler
  • ts-node: Allows running .ts files directly
  • @types/node: Provides TypeScript definitions for Node.js APIs

Installation Locations:

/usr/lib/node_modules/
├── typescript/
│ └── bin/
│ ├── tsc
│ └── tsserver
├── ts-node/
│ └── dist/
│ └── bin.js
└── @types/
└── node/

Binary Symlinks Created:

/usr/bin/tsc → /usr/lib/node_modules/typescript/bin/tsc
/usr/bin/ts-node → /usr/lib/node_modules/ts-node/dist/bin.js

Step 4: Verification and Cleanup

Purpose: Verify all installations were successful and clean up temporary files to reduce AMI size.

# Verify Node.js path
which node
# Expected: /usr/bin/node

# Verify versions
node -v
# Expected: v22.22.0

tsc -v
# Expected: Version 5.9.3

# One-command verification
echo "Node: $(node -v)"
echo "NPM: $(npm -v)"
echo "TSC: $(tsc -v)"
echo "TS-Node: $(ts-node -v)"

# Test TypeScript compilation
echo 'let message: string = "Hello, TypeScript on Ubuntu!"; console.log(message);' > hello.ts
tsc hello.ts
node hello.js
# Expected: Hello, TypeScript on Ubuntu!

# Deep cleanup (CRITICAL for AMI creation)
sudo npm cache clean --force
sudo apt-get clean
sudo rm -rf /root/.npm
sudo rm -rf /home/ubuntu/.npm

Why Cleanup is Critical:

  • npm cache: Can consume 100+ MB of disk space
  • apt cache: Contains downloaded .deb packages (50-100 MB)
  • User .npm directories: Contain cached packages and temporary files

Cleanup Results:

  • Reduces AMI size by 150-200 MB
  • Removes user-specific cache that may contain sensitive data
  • Ensures clean environment for end users

5. Using the TypeScript Environment

6.1. Compile and Run TypeScript

Basic Workflow:

# 1. Create a TypeScript file
cat > app.ts << 'EOF'
interface User {
name: string;
age: number;
}

function greet(user: User): void {
console.log(`Hello, ${user.name}! You are ${user.age} years old.`);
}

const user: User = { name: "Alice", age: 30 };
greet(user);
EOF

# 2. Compile to JavaScript
tsc app.ts

# 3. Run the compiled JavaScript
node app.js

Expected Output:

Hello, Alice! You are 30 years old.

6.2. Direct Execution with ts-node

Skip Compilation Step:

# Run TypeScript directly without creating .js file
ts-node app.ts

Expected Output:

Hello, Alice! You are 30 years old.

When to Use ts-node:

  • Quick prototyping and testing
  • Running scripts in development
  • REPL (interactive TypeScript shell)

When NOT to Use ts-node:

  • Production deployments (use pre-compiled JavaScript)
  • Performance-critical applications (compilation overhead)

6.3. Initialize a TypeScript Project

Create a Standard Project Structure:

# Create project directory
mkdir my-typescript-project
cd my-typescript-project

# Initialize npm project
npm init -y

# Generate tsconfig.json
tsc --init

Generated Files:

  1. package.json: npm project configuration
  2. tsconfig.json: TypeScript compiler configuration

Example tsconfig.json (Generated):

{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist",
"rootDir": "./src"
}
}

Project Structure:

my-typescript-project/
├── package.json
├── tsconfig.json
├── src/
│ └── index.ts
└── dist/
└── index.js (generated)

6.4. Install Project-Specific Dependencies

Example: Express Web Server with TypeScript:

# Install Express and its type definitions
npm install express
npm install --save-dev @types/express

# Create Express server
cat > src/index.ts << 'EOF'
import express, { Request, Response } from 'express';

const app = express();
const port = 3000;

app.get('/', (req: Request, res: Response) => {
res.send('Hello from TypeScript + Express!');
});

app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
EOF

# Compile and run
tsc
node dist/index.js

6.5. TypeScript REPL (Interactive Shell)

Start Interactive TypeScript:

ts-node

Example Session:

> let x: number = 42
> console.log(x * 2)
84
> interface Person { name: string }
> const person: Person = { name: "Bob" }
> person.name
'Bob'
> .exit

6. Important File Locations

File PathPurpose
/usr/bin/nodeNode.js runtime binary
/usr/bin/npmnpm package manager
/usr/bin/tscTypeScript compiler (symlink)
/usr/bin/ts-nodeTypeScript runner (symlink)
/usr/lib/node_modules/Global npm packages directory
/usr/lib/node_modules/typescript/TypeScript compiler installation
/usr/lib/node_modules/ts-node/ts-node installation
/usr/lib/node_modules/@types/node/Node.js type definitions
/etc/apt/sources.list.d/nodesource.listNodeSource repository configuration
/etc/apt/keyrings/nodesource.gpgNodeSource GPG signing key
$HOME/.npm/User-specific npm cache (safe to delete)
/root/.npm/Root user npm cache (safe to delete)

7. Troubleshooting

Issue 1: Command Not Found: tsc

Symptoms:

$ tsc -v
-bash: tsc: command not found

Diagnosis:

Check if TypeScript is installed:

npm list -g typescript

Solution:

Reinstall TypeScript globally:

sudo npm install -g typescript

Verify:

which tsc
tsc -v

Issue 2: Permission Denied When Installing Global Packages

Symptoms:

$ npm install -g some-package
Error: EACCES: permission denied, mkdir '/usr/lib/node_modules/some-package'

Diagnosis:

You are trying to install a global package without sudo.

Solution:

Use sudo for global installations:

sudo npm install -g some-package

Why This Happens:

Global npm packages install to /usr/lib/node_modules/, which is a system directory requiring root privileges.


Issue 3: TypeScript Compilation Errors

Symptoms:

$ tsc app.ts
app.ts:1:5 - error TS2322: Type 'number' is not assignable to type 'string'.

Diagnosis:

TypeScript's type checker found a type mismatch in your code.

Solution:

Fix the type error in your source code:

// Before (wrong)
let name: string = 42;

// After (correct)
let name: string = "Alice";

Understanding Type Errors:

  • TypeScript enforces type safety at compile time
  • Type errors prevent runtime bugs
  • The compiler will not generate JavaScript until all type errors are resolved

Issue 4: Module Not Found in TypeScript

Symptoms:

$ ts-node app.ts
Error: Cannot find module 'express'

Diagnosis:

You are importing a package that is not installed.

Solution:

Install the missing package:

# Install the package
npm install express

# If using TypeScript, also install type definitions
npm install --save-dev @types/express

Understanding @types Packages:

  • TypeScript needs type definitions for JavaScript libraries
  • @types/* packages provide these definitions
  • Most popular npm packages have corresponding @types packages

Issue 5: tsconfig.json Not Found

Symptoms:

$ tsc
error TS5058: The specified path does not exist: 'tsconfig.json'.

Diagnosis:

You ran tsc without a file argument, and no tsconfig.json exists.

Solution:

Generate a default configuration:

tsc --init

Or specify a file directly:

tsc app.ts

Issue 6: Node.js Version Mismatch

Symptoms:

After updating Node.js, npm commands fail or behave unexpectedly.

Diagnosis:

Check Node.js version:

node -v

Solution:

If you need to upgrade/downgrade Node.js:

# Update package list
sudo apt-get update

# Upgrade Node.js (within v22 LTS)
sudo apt-get upgrade nodejs

# Verify
node -v
npm -v

Note: The NodeSource repository is locked to v22, so apt-get upgrade will only install patch updates within the 22.x series.


8. Final Notes

Key Takeaways

  1. Node.js 22 LTS is installed system-wide via NodeSource official repository
  2. TypeScript 5.9.3 is installed globally and accessible to all users
  3. ts-node allows direct execution of TypeScript files without pre-compilation
  4. All tools are verified and tested on Ubuntu 24.04 LTS
  5. The installation is production-ready and AMI-optimized (cleaned caches)
  1. Create a Test Project:

    mkdir ~/typescript-test
    cd ~/typescript-test
    npm init -y
    tsc --init
  2. Write Your First TypeScript Application:

    echo 'console.log("Hello from TypeScript!");' > index.ts
    tsc index.ts
    node index.js
  3. Install Development Tools:

    • VS Code with TypeScript extension
    • Prettier for code formatting
    • ESLint for linting
  4. Explore TypeScript Features:

    • Interfaces and Types
    • Generics
    • Decorators
    • Async/Await
    • Union Types
  5. Build a Real Project:

    • Express.js REST API
    • CLI tool with Commander.js
    • AWS Lambda function
    • Discord/Telegram bot

Additional Resources

Support

If you encounter issues not covered in this guide:

  1. Check the troubleshooting section above
  2. Review Node.js and TypeScript official documentation
  3. Verify your security group and firewall settings
  4. Check system logs: sudo journalctl -xe

Enjoy building type-safe applications with TypeScript!