novantrio /
Fullstack-Template-MERN-like
Template siap pakai untuk proyek fullstack dengan Node.js (Express, TypeScript) di backend dan React (Vite, TypeScript, TailwindCSS) di frontend.
44/100 healthLoading repository data…
PitokDf / repository
Template backend siap pakai menggunakan Express.js, TypeScript, dan Prisma ORM. Cocok untuk membangun REST API modern, aman, dan scalable.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
Template production-ready untuk membangun REST API menggunakan Express.js, TypeScript, dan Prisma ORM dengan arsitektur yang scalable dan maintainable.
npx install-express create <nama-project>
cd <nama-project>
npm install
# Clone repository
git clone https://github.com/PitokDf/express-app-useable.git <nama-project>
cd <nama-project>
# Install dependencies
npm install
# Setup environment variables
cp .env.example .env
# Edit file .env sesuai kebutuhan
# Generate Prisma Client
npm run db:generate
# Run migrations
npm run db:migrate
# Seed database (optional)
npm run db:seed
# Start development server
npm run dev
| Script | Fungsi | Deskripsi |
|---|---|---|
npm run dev | Development server | Jalankan server dengan hot-reload, auto-restart saat file berubah |
npm run build | Build production | Compile TypeScript → JavaScript ke folder dist/ |
npm start | Run production | Jalankan compiled code dari dist/ (perlu build dulu) |
| Script | Fungsi | Deskripsi |
|---|---|---|
npm run lint | Check code | Analyze code dengan ESLint untuk error & style issues |
npm run lint:fix | Fix code | Auto-fix linting issues (format, unused imports, dll) |
| Script | Fungsi | Deskripsi |
|---|---|---|
npm test | Run tests | Jalankan semua Jest test suites |
npm run test:watch | Watch mode | Re-run tests otomatis saat file berubah (TDD) |
npm run test:coverage | Coverage report | Generate coverage report di folder coverage/ |
| Script | Fungsi | Deskripsi |
|---|---|---|
npm run db:generate | Generate client | Generate Prisma Client (run setelah update schema) |
npm run db:migrate | Apply migrations | Create & apply migration dari schema changes |
npm run db:seed | Seed data | Populate database dengan data awal dari prisma/db/seed.ts |
npm run db:studio | Database GUI | Buka Prisma Studio di http://localhost:5555 |
npm run db:reset | Reset database | ⚠️ DESTRUCTIVE: Drop DB, re-apply migrations & seed |
npm run db:prepare | Prepare client | Generate client tanpa migration (untuk CI/CD) |
express-app-useable/
├── prisma/
│ ├── schema.prisma # Database schema
│ ├── migrations/ # Database migrations
│ └── db/
│ └── seed.ts # Database seeding script
├── src/
│ ├── app.ts # Express app configuration
│ ├── index.ts # Application entry point
│ ├── config/ # Configuration files
│ │ ├── cors.ts # CORS configuration
│ │ ├── index.ts # Config exports
│ │ └── prisma.ts # Prisma client instance
│ ├── constants/ # Application constants
│ │ ├── app.ts
│ │ ├── http-status.ts # HTTP status codes
│ │ ├── message.ts # Response messages
│ │ ├── regex.ts # Regex patterns
│ │ └── time.ts # Time constants
│ ├── controller/ # Route controllers
│ │ └── user.controller.ts
│ ├── errors/ # Custom error classes
│ │ ├── app-error.ts
│ │ └── prisma-error.ts
│ ├── middleware/ # Express middlewares
│ │ ├── auth.middleware.ts # JWT authentication
│ │ ├── error.middleware.ts # Error handling
│ │ ├── logging.middleware.ts # Request logging
│ │ ├── rate-limit.middleware.ts # Rate limiting
│ │ └── zod.middleware.ts # Schema validation
│ ├── repositories/ # Data access layer
│ │ └── user.repository.ts
│ ├── routes/ # API routes
│ │ ├── index.routes.ts # Main router
│ │ └── user.route.ts # User routes
│ ├── schemas/ # Zod validation schemas
│ │ └── user.schema.ts
│ ├── service/ # Business logic layer
│ │ └── user.service.ts
│ ├── types/ # TypeScript type definitions
│ │ └── response.ts
│ ├── utils/ # Utility functions
│ │ ├── app-utils.ts
│ │ ├── auth.ts # Authentication utilities
│ │ ├── bcrypt.ts # Password hashing
│ │ ├── cache.ts # Caching utilities
│ │ ├── code-generator.ts # Unique code generation
│ │ ├── database-transaction.ts
│ │ ├── date.ts # Date utilities
│ │ ├── file-upload.ts # File upload handling
│ │ ├── health-check.ts # Health check utilities
│ │ ├── jwt.ts # JWT utilities
│ │ ├── response.ts # Response formatting
│ │ ├── string.ts # String utilities
│ │ └── winston.logger.ts # Logger configuration
│ └── validators/ # Custom validators
│ └── user.validator.ts
├── tests/ # Test files
│ └── user.integration.test.ts
├── uploads/ # Uploaded files directory
├── logs/ # Application logs
├── .env # Environment variables
├── .env.example # Environment variables template
├── Dockerfile # Docker configuration
├── docker-compose.yml # Docker Compose configuration
├── tsconfig.json # TypeScript configuration
├── jest.config.js # Jest configuration
├── eslint.config.cjs # ESLint configuration
├── package.json # Dependencies dan scripts
└── README.md # Documentation
Template ini menggunakan Clean Architecture dengan pattern: Repository → Service → Controller
Service layer berisi business logic aplikasi. Contoh product.service.ts:
// src/service/product.service.ts
import { HttpStatus } from "@/constants/http-status";
import { Messages } from "@/constants/message";
import { AppError } from "@/errors/app-error";
import { ProductRepository } from "@/repositories/product.repository";
import { CreateProductInput } from "@/schemas/product.schema";
import { cacheManager } from "@/utils/cache";
import logger from "@/utils/winston.logger";
// Get all products dengan pagination & caching
export async function getAllProductService(query?: {
page?: number;
limit?: number;
}) {
const page = query?.page || 1;
const limit = query?.limit || 10;
const skip = (page - 1) * limit;
const cacheKey = `products:all:page:${page}:limit:${limit}`;
// Cek cache dulu
const cached = cacheManager.get(cacheKey);
if (cached) return cached;
// Ambil dari database
const [products, total] = await Promise.all([
ProductRepository.findAllOptimized({ skip, take: limit }),
ProductRepository.count(),
]);
const result = {
data: products,
pagination: {
page,
limit,
total,
totalPages: Math.ceil(total / limit),
hasNextPage: page < Math.ceil(total / limit),
hasPrevPage: page > 1,
},
};
// Simpan ke cache (5 menit)
cacheManager.set(cacheKey, result, 300);
return result;
}
// Get product by ID
export async function getProductByIdService(id: string) {
const product = await ProductRepository.findById(id);
if (!product) throw new AppError(Messages.NOT_FOUND, HttpStatus.NOT_FOUND);
return product;
}
// Create product
export async function createProductService(data: CreateProductInput) {
// Business logic: validasi price
if (data.price <= 0) {
throw new AppError("Price must be greater than 0", HttpStatus.BAD_REQUEST);
}
const product = await ProductRepository.create(data);
// Invalidate cache setelah create
cacheManager.delPattern("products:all:page:");
logger.info("Product created", { productId: product.id });
return product;
}
// Update & Delete service... (similar pattern)
Key Points:
AppError untuk error handlingRepository layer untuk database operations saja (no business logic). Contoh product.repository.ts:
// src/repositories/product.repository.ts
import { Product } from "@prisma/client";
import { db } from "@/config/prisma";
export class ProductRepository {
static async findById(id: string): Promise<Product | null> {
return db.product.findUnique({ where: { id } });
}
// Optimized: select specific fields only
static async findAllOptimized(options?: { skip?: number; take?: number }) {
return db.product.findMany({
select: {
id: true,
name: true,
price: true,
description: true,
},
skip: options?.skip,
take: options?.take,
orderBy: { createdAt: "desc" },
});
}
static async count(): Promise<number> {
return db.product.count();
}
static async create(
data: Pick<Product, "name" | "price" | "description">
): Promise<Product> {
return db.product.create({ data });
}
static async update(
id: string,
data: Partial<Pick<Product, "name" | "price">>
): Promise<Product> {
return db.product.update({ where: { id }, data });
}
static async delete(id: string): Promise<Product> {
return db.product.delete({ where: { id } });
}
}
Key Points:
Controller menangani HTTP requests dan responses. Contoh product.controller.ts:
// src/controller/product.controller.ts
import { Request, Respons
Selected from shared topics, language and repository description—not editorial ratings.
novantrio /
Template siap pakai untuk proyek fullstack dengan Node.js (Express, TypeScript) di backend dan React (Vite, TypeScript, TailwindCSS) di frontend.
44/100 healthLutfiyaAinurrahmanP /
Template backend NestJS dengan setup siap pakai untuk pengembangan REST API modern berbasis TypeScript. Menggunakan Prisma untuk ORM, Class Validator untuk validasi, Winston untuk logging, serta Jest untuk testing. Cocok sebagai fondasi proyek backend yang terstruktur, scalable, dan production-ready.
34/100 healthLutfiyaAinurrahmanP /
Template backend Express.js + TypeScript dengan setup siap pakai untuk pengembangan REST API modern. Menggunakan Prisma untuk ORM, Zod untuk validasi, Winston untuk logging, serta Jest + Supertest untuk testing. Cocok sebagai dasar proyek backend dengan struktur modular, clean, dan scalable.
LutfiyaAinurrahmanP /
Template backend Express.js + TypeScript dengan setup siap pakai untuk pengembangan REST API modern. Menggunakan Prisma untuk ORM, Zod untuk validasi, Winston untuk logging, serta Jest + Supertest untuk testing. Cocok sebagai dasar proyek backend dengan struktur modular, clean, dan scalable.
34/100 health