Skip to content
OpenSmartRoute
Skillv1.0.0

replit-core-workflow-a

Build a full-stack web app on Replit with Express/Flask, PostgreSQL, Auth, and deployment. Use when creating a new production app on Replit from scratch, building the primary user-facing workflow, or

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (plugins/saas-packs/replit-pack/skills/replit-core-workflow-a/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill replit-core-workflow-a. Copyright stays with the author (MIT).

Replit Core Workflow A — Full-Stack App

Overview

Build a production-ready web app on Replit: Express or Flask server, PostgreSQL database, Replit Auth for user login, Object Storage for file uploads, and Autoscale deployment. This is the primary money-path workflow for shipping apps on Replit.

Prerequisites

  • Replit account (Core plan or higher for deployments)
  • .replit and replit.nix configured (see replit-install-auth)
  • PostgreSQL provisioned in the Database pane

Instructions

Step 1: Project Structure

my-app/
├── .replit                 # Run + deployment config
├── replit.nix              # System dependencies
├── package.json
├── tsconfig.json
├── src/
│   ├── index.ts            # Express entry point
│   ├── routes/
│   │   ├── api.ts          # API endpoints
│   │   ├── auth.ts         # Auth routes
│   │   └── health.ts       # Health check
│   ├── services/
│   │   ├── db.ts           # PostgreSQL pool
│   │   └── storage.ts      # Object Storage
│   └── middleware/
│       ├── auth.ts         # Replit Auth middleware
│       └── errors.ts       # Error handler
└── tests/

Step 2: Configuration Files

# .replit
entrypoint = "src/index.ts"
run = "npx tsx src/index.ts"

modules = ["nodejs-20:v8-20230920-bd784b9"]

[nix]
channel = "stable-24_05"

[env]
NODE_ENV = "development"

[deployment]
run = ["sh", "-c", "npx tsx src/index.ts"]
build = ["sh", "-c", "npm ci"]
deploymentTarget = "autoscale"
# replit.nix
{ pkgs }: {
  deps = [
    pkgs.nodejs-20_x
    pkgs.nodePackages.typescript-language-server
    pkgs.postgresql
  ];
}

Step 3: Database Layer

// src/services/db.ts
import { Pool } from 'pg';

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: { rejectUnauthorized: false },
  max: 10,
  idleTimeoutMillis: 30000,
  connectionTimeoutMillis: 5000,
});

// Initialize schema
export async function initDB() {
  await pool.query(`
    CREATE TABLE IF NOT EXISTS users (
      id TEXT PRIMARY KEY,
      username TEXT UNIQUE NOT NULL,
      profile_image TEXT,
      created_at TIMESTAMPTZ DEFAULT NOW()
    );
    CREATE TABLE IF NOT EXISTS posts (
      id SERIAL PRIMARY KEY,
      user_id TEXT REFERENCES users(id),
      title TEXT NOT NULL,
      content TEXT NOT NULL,
      created_at TIMESTAMPTZ DEFAULT NOW()
    );
  `);
}

export async function upsertUser(id: string, username: string, image: string) {
  return pool.query(
    `INSERT INTO users (id, username, profile_image)
     VALUES ($1, $2, $3)
     ON CONFLICT (id) DO UPDATE SET username = $2, profile_image = $3
     RETURNING *`,
    [id, username, image]
  );
}

export async function createPost(userId: string, title: string, content: string) {
  return pool.query(
    'INSERT INTO posts (user_id, title, content) VALUES ($1, $2, $3) RETURNING *',
    [userId, title, content]
  );
}

export async function getPosts(limit = 20) {
  return pool.query(
    `SELECT p.*, u.username, u.profile_image
     FROM posts p JOIN users u ON p.user_id = u.id
     ORDER BY p.created_at DESC LIMIT $1`,
    [limit]
  );
}

export { pool };

Step 4: Auth Middleware

// src/middleware/auth.ts
import { Request, Response, NextFunction } from 'express';
import { upsertUser } from '../services/db';

export interface AuthedRequest extends Request {
  user: { id: string; name: string; image: string };
}

export async function requireAuth(req: Request, res: Response, next: NextFunction) {
  const userId = req.headers['x-replit-user-id'] as string;
  if (!userId) return res.status(401).json({ error: 'Login required' });

  const name = (req.headers['x-replit-user-name'] as string) || '';
  const image = (req.headers['x-replit-user-profile-image'] as string) || '';

  // Upsert user in database on every authenticated request
  await upsertUser(userId, name, image);
  (req as any).user = { id: userId, name, image };
  next();
}

Step 5: API Routes

// src/routes/api.ts
import { Router } from 'express';
import { requireAuth, AuthedRequest } from '../middleware/auth';
import { createPost, getPosts } from '../services/db';
import { Client as StorageClient } from '@replit/object-storage';

const router = Router();
const storage = new StorageClient();

// Public: list posts
router.get('/posts', async (req, res) => {
  const { rows } = await getPosts();
  res.json(rows);
});

// Protected: create post
router.post('/posts', requireAuth, async (req, res) => {
  const { title, content } = req.body;
  const user = (req as AuthedRequest).user;
  const { rows } = await createPost(user.id, title, content);
  res.status(201).json(rows[0]);
});

// Protected: upload file to Object Storage
router.post('/upload', requireAuth, async (req, res) => {
  const user = (req as AuthedRequest).user;
  const filename = `uploads/${user.id}/${Date.now()}-${req.body.name}`;
  await storage.uploadFromText(filename, req.body.content);
  res.json({ path: filename });
});

export default router;

Step 6: Entry Point

// src/index.ts
import express from 'express';
import { initDB, pool } from './services/db';
import apiRoutes from './routes/api';

const app = express();
app.use(express.json());

// Health check (required for Replit deployments)
app.get('/health', async (req, res) => {
  try {
    await pool.query('SELECT 1');
    res.json({ status: 'ok', uptime: process.uptime() });
  } catch {
    res.status(503).json({ status: 'degraded' });
  }
});

// Auth info endpoint (client-side: GET /__replauthuser)
app.get('/api/me', (req, res) => {
  const id = req.headers['x-replit-user-id'];
  if (!id) return res.json({ loggedIn: false });
  res.json({
    loggedIn: true,
    id,
    name: req.headers['x-replit-user-name'],
    image: req.headers['x-replit-user-profile-image'],
  });
});

app.use('/api', apiRoutes);

const PORT = parseInt(process.env.PORT || '3000');
initDB().then(() => {
  app.listen(PORT, '0.0.0.0', () => {
    console.log(`Server running on port ${PORT}`);
  });
});

Error Handling

Error Cause Solution
DATABASE_URL undefined PostgreSQL not provisioned Create database in Database pane
Auth headers empty Running in dev mode Auth only works on deployed .replit.app
Object Storage 403 No bucket created Provision bucket in Object Storage pane
Port conflict Multiple services on same port Use different ports, set ignorePorts

Resources

Next Steps

For collaboration and admin workflows, see replit-core-workflow-b.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-replit-core-w-999a11/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-replit-core-w-999a11.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-replit-core-w-999a11",
  "kind": "skill",
  "name": "replit-core-workflow-a",
  "description": "Build a full-stack web app on Replit with Express/Flask, PostgreSQL, Auth, and deployment. Use when creating a new production app on Replit from scratch, building the primary user-facing workflow, or following Replit best practices. Trigger with phrases like \"build replit app\", \"replit full stack\", \"replit web app\", \"create replit project\", \"replit express flask\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "general"
    ],
    "tags": [
      "skill-md",
      "saas",
      "replit",
      "workflow",
      "full-stack",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Build a full-stack web app on Replit with Express/Flask, PostgreSQL, Auth, and deployment. Use when creating a new production app on Replit from scratch, building the primary user-facing workflow, or following Replit best practices. Trigger with phrases like \"build replit app\", \"replit full stack\", \"replit web app\", \"create replit project\", \"replit express flask\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "plugins/saas-packs/replit-pack/skills/replit-core-workflow-a/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/plugins/saas-packs/replit-pack/skills/replit-core-workflow-a/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/plugins/saas-packs/replit-pack/skills/replit-core-workflow-a/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Read,",
      "Write,",
      "Edit,",
      "Bash(npm:*),",
      "Bash(pip:*),",
      "Grep"
    ],
    "license": "MIT"
  },
  "instructions": "# Replit Core Workflow A — Full-Stack App\n\n## Overview\n\nBuild a production-ready web app on Replit: Express or Flask server, PostgreSQL database, Replit Auth for user login, Object Storage for file uploads, and Autoscale deployment. This is the primary money-path workflow for shipping apps on Replit.\n\n## Prerequisites\n\n- Replit account (Core plan or higher for deployments)\n- `.replit` and `replit.nix` configured (see `replit-install-auth`)\n- PostgreSQL provisioned in the Database pane\n\n## Instructions\n\n### Step 1: Project Structure\n\n```\nmy-app/\n├── .replit                 # Run + deployment co",
  "cost": {
    "context_tokens": 1745
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-replit-core-w-999a11/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.