Tailr is a full-stack social discovery app for urban places. It combines a React + Vite client with an Express API, using PostgreSQL (via Drizzle ORM and Neon) for persistence.
Overview
Tailr is a full-stack social discovery app for urban places. It combines a React + Vite client with an Express API, using PostgreSQL (via Drizzle ORM and Neon) for persistence. - Place discovery and search - User accounts with session-based authentication - Social features (posts, comments, likes, follows, saved places) - Lists, reviews, notifications, and story-like content - Community place photo uploads (with optional Replit Object Storage integration) The app runs as a single Node.js service that serves both: - JSON API routes under /api/* - The web client (Vite middleware in development, static assets in production) - Node.js (recommended: 20.
README
Tailr
Tailr is a full-stack social discovery app for urban places. It combines a React + Vite client with an Express API, using PostgreSQL (via Drizzle ORM and Neon) for persistence.
Table of Contents
- Overview
- Tech Stack
- Repository Structure
- Getting Started
- Environment Variables
- Available Scripts
- Database and Schema
- API Overview
- Deployment
- Troubleshooting
- Contributing
- License
Overview
Tailr provides:
- Place discovery and search
- User accounts with session-based authentication
- Social features (posts, comments, likes, follows, saved places)
- Lists, reviews, notifications, and story-like content
- Community place photo uploads (with optional Replit Object Storage integration)
The app runs as a single Node.js service that serves both:
- JSON API routes under
/api/* - The web client (Vite middleware in development, static assets in production)
Tech Stack
Backend
- Node.js (recommended:
20.x) - Express
- TypeScript
- Drizzle ORM
- Neon serverless PostgreSQL driver
- Session auth with
express-session+memorystore
Frontend
- React
19 - Vite
7 - Wouter
- TanStack Query
- Tailwind CSS
4 - Leaflet / React Leaflet
Tooling
tsxfor TypeScript runtime scriptsesbuildfor server bundling in production buildsdrizzle-kitfor database schema push
Repository Structure
.
|- client/ # React app (UI, routes, hooks, components)
|- server/ # Express app, API routes, auth, storage layer
|- shared/ # Shared Drizzle schema + Zod insert schemas
|- script/ # Build pipeline script (client + server outputs)
|- scripts/ # Operational shell scripts (for example post-merge)
|- attached_assets/ # Static assets served by Express
|- drizzle.config.ts # Drizzle configuration
|- vite.config.ts # Vite config (dev + build outDir)
|- tsconfig.json # TypeScript config + path aliases
`- .replit # Replit runtime and deployment config
Getting Started
Prerequisites
- Node.js
20.x - npm
9+(or compatible) - A PostgreSQL database URL (
DATABASE_URL)
1) Install dependencies
npm install
2) Configure environment variables
Create a local environment file or set environment variables in your shell/hosting provider.
# Example .env values
DATABASE_URL=postgres://user:password@host:5432/dbname
SESSION_SECRET=replace-with-a-long-random-secret
PORT=5000
NODE_ENV=development
GOOGLE_API_KEY=optional
3) Apply schema to your database
npm run db:push
4) Start development server
npm run dev
The app is expected to run on http://localhost:5000.
Windows note
The scripts in package.json use Unix-style inline env assignments (NODE_ENV=...). If npm run dev or npm run start fails in PowerShell/CMD, use:
$env:NODE_ENV="development"; npx tsx server/index.ts
For production locally:
npm run build
$env:NODE_ENV="production"; node dist/index.cjs
Environment Variables
| Name | Required | Used in | Description |
|---|---|---|---|
DATABASE_URL |
Yes | server + Drizzle | PostgreSQL connection string for app runtime and schema push. |
SESSION_SECRET |
Yes in production | auth/session setup | Cookie session secret. Dev fallback exists but should not be used in production. |
PORT |
No (default 5000) |
server startup | Port for the combined API + web server. |
NODE_ENV |
Recommended | server/build behavior | development enables Vite middleware; production serves static build. |
GOOGLE_API_KEY |
Optional | place/photo routes | Enables Google Places lookups and photo enrichment. |
PUBLIC_OBJECT_SEARCH_PATHS |
Optional/Replit | object storage | Required for some Replit Object Storage upload/list flows. |
PRIVATE_OBJECT_DIR |
Optional/Replit | object storage | Required for some Replit Object Storage upload/list flows. |
REPLIT_ID |
Optional/Replit dev | Vite config | Enables Replit-only dev plugins when not in production. |
REPLIT_INTERNAL_APP_DOMAIN |
Optional/Replit deploy | meta image plugin | Used for absolute social image URL rewriting. |
REPLIT_DEV_DOMAIN |
Optional/Replit dev | meta image plugin | Used for dev URL rewriting for social images. |
Available Scripts
From package.json:
npm run dev- Start Express in development mode (tsx server/index.ts).npm run dev:client- Start only the Vite client on port5000.npm run build- Build client assets and bundle server intodist/.npm run start- Start the production server fromdist/index.cjs.npm run check- TypeScript type-check.npm run db:push- Push Drizzle schema to the configured database.
Database and Schema
- Drizzle config:
drizzle.config.ts - Schema source of truth:
shared/schema.ts - Runtime storage implementation:
server/storage.ts - Output migrations directory:
migrations/(as configured in Drizzle)
Typical DB workflow:
- Update table/schema definitions in
shared/schema.ts. - Run
npm run db:pushto apply changes. - Restart dev server if needed.
API Overview
Primary routes live in server/routes.ts, including:
- Auth:
/api/auth/* - Users and social graph:
/api/users/*,/api/follow* - Places and search:
/api/places* - Posts and engagement:
/api/posts*,/api/comments* - Saved places and lists:
/api/saved*,/api/lists* - Reviews and notifications:
/api/places/:id/reviews*,/api/notifications* - Stories and suggestions:
/api/stories*,/api/suggestions - Upload helpers/object storage integration: routes under
/api/uploads/*and/objects/*
Deployment
The repository includes Replit deployment configuration in .replit:
- Build command:
npm run build - Run command:
npm run start - Deployment target: autoscale
- Port mapping: local
5000to external80
For non-Replit deployments, ensure:
DATABASE_URLandSESSION_SECRETare set.npm run buildruns during CI/build phase.- Runtime starts
node dist/index.cjswithNODE_ENV=production.
Troubleshooting
-
DATABASE_URL must be set
EnsureDATABASE_URLexists in your shell or deployment secrets before runningdb:push,dev, orstart. -
Session/auth issues in production
Set a strongSESSION_SECRETand verify cookie/domain/HTTPS behavior for your deployment. -
Google photo/places data missing
SetGOOGLE_API_KEYand verify Places API access in your Google Cloud project. -
Port already in use (
5000)
Stop the existing process or setPORTto an open port for local runs. -
Windows script env assignment errors
Use the PowerShell commands in the Windows note section.
Contributing
- Create a feature branch.
- Keep changes scoped and documented.
- Run:
npm run checknpm run build(recommended before opening PR)
- Submit a PR with:
- What changed
- Why it changed
- How it was tested
License
MIT (see package.json).
Recommended Tools
Try a different keyword or remove a filter.
Install
npx skillfish add kedylind/tailr