Saltar al contenido
Boilerplate de e-commerce open source

Clona el repo. Lanza una tienda.

Una tienda, un panel de administración y pago con Stripe listos para producción en un repo. Cambia el backend, conserva la app.

0variables de entorno para arrancar
El catálogo de demostración sirve la tienda hasta que conectes una.
4backends, una interfaz
Demo, Firebase, Supabase, Postgres. Adaptadores, no forks.
18productos de demostración
Filtros, búsqueda, variantes y stock, ya poblados.
2idiomas, 4 monedas
Resueltos en el servidor, así el primer render ya es correcto.

Una interfaz de comercio. Cambia el backend.

Cada llamada de la tienda y del panel pasa por un módulo de comercio tipado. Cambia el adaptador y conserva la app.

.env.local

NEXT_PUBLIC_COMMERCE_BACKEND=firebase
Implemented in
src/lib/commerce/firebase.ts
Credentials
NEXT_PUBLIC_FIREBASE_*

Predeterminado sin configuración. Las reglas de Firestore vienen en el repo.

Cumple esto y la app funcionasrc/lib/commerce/types.ts

Siete servicios, un objeto. Todas las llamadas de la tienda y de la administración pasan por él; por eso un adaptador es un archivo nuevo y no un fork.

export interface CommerceServices {
  products:   ProductService;
  carts:      CartService;
  quotes:     QuoteService;
  orders:     OrderService;
  discounts:  DiscountService;
  customers:  CustomerService;
  admin:      AdminService;
}

// one of the seven, in full:
interface ProductService {
  list(pageSize?: number, cursor?: PageCursor | null): Promise<ProductPage>;
  getById(id: string): Promise<Product | null>;
  search(term: string, maxResults?: number): Promise<Product[]>;
  create(product: Product): Promise<void>;
  update(id: string, data: Partial<Product>): Promise<void>;
  delete(id: string): Promise<void>;
  listFeatured(): Promise<Product[]>;
  feature(product: Product): Promise<void>;
  unfeature(featuredId: string): Promise<void>;
}
A dónde va una llamada

Una línea de código. Cuatro destinos posibles.

La misma línea de la tienda llega a un catálogo incluido, a Firestore o a una base SQL. Lo que cambia es qué adaptador responde, y si la respuesta viene del navegador o del servidor.

Cualquier llamada de tienda o administración

await commerce.products.list()

Una interfaz tipada CommerceServices

En el navegador

  • Demounset

    src/lib/commerce/demo

    Catálogo incluido. Sin red ni credenciales.

  • Firebasefirebase

    src/lib/commerce/firebase.ts

    Lecturas directas desde el navegador; las reglas mandan.

En el servidor

POST /api/commerce/[service]/[method]
Verifica el token, comprueba el rol y registra la auditoría

  • Supabase / Prismasupabase · postgres

    src/lib/commerce/server/*.ts

    Las credenciales privilegiadas nunca salen del servidor.

  • Admin writesany backend

    src/lib/commerce/server/firebase-admin.ts

    Escrituras de administración, viva donde viva el dato.

Todo lo que necesita una tienda real, ya conectado.

Studio Headphones X1

Northsound

Studio Headphones X1

AUD-001

$129.99

Audio

Panel de administración

CRUD de productos, medios, pedidos y flujo de cotizaciones.

Cotizaciones y pago con Stripe

Como invitado o con sesión, con webhooks verificados por firma.

Multi-idioma y multi-moneda

Enrutamiento por idioma y cambio de moneda en vivo, incluidos.

Inventario y roles

Conteo de stock, estados sin stock y acceso de administrador por rol.

Lo que lo sostiene

Las partes fáciles de equivocar, ya resueltas.

Un starter solo merece un fork si sus cimientos aguantan el contacto con producción. Estos son los que normalmente no lo hacen.

  • El checkout no puede vender de más

    api/webhooks/stripe/route.ts

    El webhook de Stripe escribe el pedido y cada descuento de stock en una sola transacción, con la clave de la sesión. Un reenvío toca el mismo documento; dos simultáneos no pueden gastar la última unidad.

  • Las escrituras de administración quedan auditadas

    lib/commerce/server/audit.ts

    Las mutaciones privilegiadas pasan por el servidor, que vuelve a comprobar el rol y registra quién cambió qué con su propio reloj. Un administrador no puede omitir ni retrasar la entrada.

  • Los precios salen del catálogo

    api/checkout/route.ts

    La ruta de checkout vuelve a leer cada producto y variante en el servidor. Nada de lo que envía el navegador mueve un importe.

  • Cada push pasa por el control

    .github/workflows/ci.yml

    Lint, tipos, la suite de pruebas y una compilación de producción sin ninguna credencial. El backend de demostración es lo que hace posible esto último.

Código abierto. Auto-alojable. Tuyo para clonar.

git clone github.com/nebulanollie/ecommerce-boilerplate

Funciona sin configuración. Conecta un backend cuando quieras datos reales.