npm install express
npm install -D typescript ts-node nodemon @types/node @types/express
npx tsc --init
mkdir src
npm install dotenv
npm install typeorm reflect-metadata mysql2
npm install -D @types/node
npm install multer
npm install -D @types/multer
npm run dev
create directory public/upload
in src create config,routes,enity folder
inside config\data-ssource.ts
import "reflect-metadata";
import { DataSource } from "typeorm";
import { User } from "../entity/User";
export const AppDataSource = new DataSource({
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "sangram#81",
database: "myapp",
synchronize: true, // auto create tables (dev only)
logging: false,
entities: [User],
});
inside config\multer.ts
import multer from "multer";
import path from "path";
// storage config
const storage = multer.diskStorage({
destination: function (_, __, cb) {
cb(null, path.join(__dirname, "../../public/uploads"));
},
filename: function (_, file, cb) {
const uniqueName = Date.now() + "-" + file.originalname;
cb(null, uniqueName);
},
});
export const upload = multer({
storage,
fileFilter: (_, file, cb) => {
if (file.mimetype.startsWith("image/")) {
cb(null, true);
} else {
cb(new Error("Only images allowed"));
}
},
});
inside tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"rootDir": "src",
"outDir": "dist",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
inside package.json
{
"dependencies": {
"dotenv": "^17.4.2",
"express": "^5.2.1",
"multer": "^2.1.1",
"mysql2": "^3.22.0",
"reflect-metadata": "^0.2.2",
"typeorm": "^0.3.28"
},
"devDependencies": {
"@types/express": "^5.0.6",
"@types/multer": "^2.1.0",
"@types/node": "^25.6.0",
"nodemon": "^3.1.14",
"ts-node": "^10.9.2",
"typescript": "^6.0.2"
},
"scripts": {
"dev": "nodemon --watch src --ext ts --exec \"npx ts-node src/main.ts\"",
"build": "tsc",
"start": "node dist/main.js"
}
}
inside .env
PORT=3000
NODE_ENV=development
inside enity/User.ts
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id!: number;
@Column()
name!: string;
@Column()
email!: string;
}
This should create user table not users.
inside routes\uploadRoutes.ts
import { Router } from "express";
import { upload } from "../config/multer";
const router = Router();
// single file upload
router.post("/", upload.single("file"), (req, res) => {
if (!req.file) {
return res.status(400).json({ message: "No file uploaded" });
}
return res.json({
message: "File uploaded",
file: req.file.filename,
url: `/uploads/${req.file.filename}`,
});
});
export default router;
inside routes/userRotes.ts
import { Router } from "express";
import { AppDataSource } from "../config/data-source";
import { User } from "../entity/User";
const router = Router();
router.get("/", (_, res) => {
res.json([{ id: 1, name: "Sangram" }]);
});
router.get("/account", async (req, res) => {
const userRepo = AppDataSource.getRepository(User);
const users = await userRepo.find();
res.json(users);
});
export default router;
src\main.ts
import express from "express";
import "dotenv/config";
const PORT = process.env.PORT || 3000;
import userRoutes from "./routes/userRoutes";
import path from "path";
import "reflect-metadata";
import { AppDataSource } from "./config/data-source";
import { User } from "./entity/User";
const app = express();
import uploadRoutes from "./routes/uploadRoutes";
app.use(express.json());
app.use(express.static(path.join(__dirname, "../public")));
app.use("/uploads", express.static(path.join(__dirname, "../public/uploads")));
app.use("/upload", uploadRoutes);
app.use("/users", userRoutes);
AppDataSource.initialize()
.then(() => {
console.log("DB connected");
const userRepo = AppDataSource.getRepository(User);
app.get("/", (_, res) => {
res.send("API is running 🚀");
});
app.get("/account", async (_, res) => {
const users = await userRepo.find();
res.json(users);
});
app.post("/account", async (req, res) => {
const user = userRepo.create(req.body);
const result = await userRepo.save(user);
res.json(result);
});
to compile project from typesscript to javascript run
npx tsc
then run
npm start
app.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
})
.catch((err) => console.log("DB error:", err));
to run project
npm run dev
Code is available at gitsangramdesai/typescript-express-typeorm-multer
Here slight changes are made to use clustering.