Skip to main content 홈 크리에이터 jeremylongshore claude-code-plugins-plus-skills replit-sdk-patterns
replit-sdk-patterns Apply production-ready patterns for Replit Database, Object Storage, and Auth APIs.
Use when implementing Replit integrations, structuring data access layers,
or establishing team coding standards for Replit services.
Trigger with phrases like "replit patterns", "replit best practices",
"replit code patterns", "idiomatic replit", "replit SDK".
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill replit-sdk-patterns명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... 이 저장소의 다른 Skills Implement user sign-up and sign-in flows with Clerk.
Use when building authentication UI, customizing sign-in experience,
or implementing OAuth social login.
Trigger with phrases like "clerk sign-in", "clerk sign-up",
"clerk login flow", "clerk OAuth", "clerk social login".
Implement session management and middleware with Clerk.
Use when managing user sessions, configuring route protection,
or implementing token refresh and custom JWT templates.
Trigger with phrases like "clerk session", "clerk middleware",
"clerk route protection", "clerk token", "clerk JWT".
Configure enterprise SSO, role-based access control, and organization management.
Use when implementing SSO integration, configuring role-based permissions,
or setting up organization-level controls.
Trigger with phrases like "clerk SSO", "clerk RBAC",
"clerk enterprise", "clerk roles", "clerk permissions", "clerk organizations".
jeremylongshore
jeremylongshore/claude-code-plugins-plus-skills
GitHub 저장소 열기 name replit-sdk-patterns description Apply production-ready patterns for Replit Database, Object Storage, and Auth APIs.
Use when implementing Replit integrations, structuring data access layers,
or establishing team coding standards for Replit services.
Trigger with phrases like "replit patterns", "replit best practices",
"replit code patterns", "idiomatic replit", "replit SDK".
allowed-tools Read, Write, Edit version 1.12.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","replit","python","typescript","patterns"] compatibility Designed for Claude Code, also compatible with Codex and OpenClaw
Replit SDK Patterns
Overview
Production-ready patterns for Replit's built-in services: Key-Value Database (@replit/database / replit.db), Object Storage (@replit/object-storage), PostgreSQL (DATABASE_URL), and Auth headers. Covers singleton clients, error handling, and type-safe wrappers.
Prerequisites
.replit and replit.nix configured (see replit-install-auth)
Familiarity with async/await patterns
Understanding of Replit's service model
Instructions
Step 1: Database Client Singleton (Node.js)
import Database from '@replit/database' ;
let instance : Database | null = null ;
export function getKV ( ): Database {
if (!instance) {
instance = new Database ();
}
return instance;
}
export async function kvGet<T>(key : string ): Promise <T | null > {
const value = await getKV ().get (key);
return value as T | null ;
}
export async function kvSet<T>( : , : T): < > {
(). (key, value);
}
( ): < []> {
(). (prefix);
}
( ): < > {
(). (key);
}
key
string
value
Promise
void
await
getKV
set
export
async
function
kvList
prefix = ''
Promise
string
return
getKV
list
export
async
function
kvDelete
key : string
Promise
void
await
getKV
delete
Step 2: Object Storage Wrapper
import { Client } from '@replit/object-storage' ;
let storage : Client | null = null ;
export function getStorage ( ): Client {
if (!storage) {
storage = new Client ();
}
return storage;
}
export async function uploadText (path : string , content : string ): Promise <void > {
try {
await getStorage ().uploadFromText (path, content);
} catch (err : any ) {
if (err.name === 'BucketNotFoundError' ) {
throw new Error ('Object Storage bucket not provisioned. Create one in the Object Storage pane.' );
}
if (err.name === 'TooManyRequestsError' ) {
throw new Error ('Object Storage rate limited. Retry after backoff.' );
}
throw err;
}
}
export async function downloadText (path : string , fallback = '' ): Promise <string > {
try {
const { value } = await getStorage ().downloadAsText (path);
return value ?? fallback;
} catch {
return fallback;
}
}
export async function listObjects (prefix : string ): Promise <string []> {
const objects = await getStorage ().list ({ prefix });
return objects.map (obj => obj.name );
}
Step 3: PostgreSQL Connection Pool
import { Pool , PoolConfig } from 'pg' ;
let pool : Pool | null = null ;
export function getPool ( ): Pool {
if (!pool) {
if (!process.env .DATABASE_URL ) {
throw new Error ('DATABASE_URL not set. Provision PostgreSQL in the Database pane.' );
}
const config : PoolConfig = {
connectionString : process.env .DATABASE_URL ,
ssl : { rejectUnauthorized : false },
max : 10 ,
idleTimeoutMillis : 30000 ,
connectionTimeoutMillis : 5000 ,
};
pool = new Pool (config);
pool.on ('error' , (err ) => {
console .error ('PostgreSQL pool error:' , err.message );
});
}
return pool;
}
export async function query<T>(sql : string , params ?: any []): Promise <T[]> {
const result = await getPool ().query (sql, params);
return result.rows as T[];
}
export async function withTransaction<T>(
fn : (client : import ('pg' ).PoolClient ) => Promise <T>
): Promise <T> {
const client = await getPool ().connect ();
try {
await client.query ('BEGIN' );
const result = await fn (client);
await client.query ('COMMIT' );
return result;
} catch (err) {
await client.query ('ROLLBACK' );
throw err;
} finally {
client.release ();
}
}
Step 4: Auth Middleware Pattern
import { Request , Response , NextFunction } from 'express' ;
export interface ReplitUser {
id : string ;
name : string ;
bio : string ;
url : string ;
profileImage : string ;
roles : string ;
teams : string ;
}
export function extractUser (req : Request ): ReplitUser | null {
const id = req.headers ['x-replit-user-id' ] as string ;
if (!id) return null ;
return {
id,
name : (req.headers ['x-replit-user-name' ] as string ) || '' ,
bio : (req.headers ['x-replit-user-bio' ] as string ) || '' ,
url : (req.headers ['x-replit-user-url' ] as string ) || '' ,
profileImage : (req.headers ['x-replit-user-profile-image' ] as string ) || '' ,
roles : (req.headers ['x-replit-user-roles' ] as string ) || '' ,
teams : (req.headers ['x-replit-user-teams' ] as string ) || '' ,
};
}
export function requireAuth (req : Request , res : Response , next : NextFunction ) {
const user = extractUser (req);
if (!user) return res.status (401 ).json ({ error : 'Login required' });
(req as any ).user = user;
next ();
}
Step 5: Python Patterns
from replit import db
from replit.object_storage import Client as ObjectStorage
import os, json
class KVStore :
@staticmethod
def get (key: str , default=None ):
return db.get(key, default)
@staticmethod
def set (key: str , value ):
db[key] = value
@staticmethod
def delete (key: str ):
if key in db:
del db[key]
@staticmethod
def list_keys (prefix: str = '' ) -> list :
return db.prefix(prefix) if prefix else list (db.keys())
class FileStore :
def __init__ (self ):
self ._client = ObjectStorage()
def upload (self, path: str , content: str ):
self ._client.upload_from_text(path, content)
def download (self, path: str ) -> str :
return self ._client.download_as_text(path)
def exists (self, path: str ) -> bool :
return self ._client.exists(path)
def delete (self, path: str ):
self ._client.delete(path)
def list (self, prefix: str = '' ) -> list :
return [obj.name for obj in self ._client.list (prefix=prefix)]
def get_replit_user (request ) -> dict | None :
user_id = request.headers.get('X-Replit-User-Id' )
if not user_id:
return None
return {
'id' : user_id,
'name' : request.headers.get('X-Replit-User-Name' , '' ),
'roles' : request.headers.get('X-Replit-User-Roles' , '' ),
'image' : request.headers.get('X-Replit-User-Profile-Image' , '' ),
}
Step 6: Retry with Backoff
export async function withRetry<T>(
fn : () => Promise <T>,
opts = { maxRetries : 3 , baseMs : 1000 , maxMs : 30000 }
): Promise <T> {
for (let attempt = 0 ; attempt <= opts.maxRetries ; attempt++) {
try {
return await fn ();
} catch (err : any ) {
if (attempt === opts.maxRetries ) throw err;
const delay = Math .min (opts.baseMs * 2 ** attempt, opts.maxMs );
const jitter = Math .random () * delay * 0.1 ;
await new Promise (r => setTimeout (r, delay + jitter));
}
}
throw new Error ('Unreachable' );
}
Error Handling Pattern Use Case Benefit Singleton client All services Avoids connection leaks Typed wrappers KV/SQL queries Catches schema issues at compile time Retry + backoff Transient failures Handles cold starts and rate limits Transaction helper Multi-step writes Atomic operations, safe rollback
Resources
Next Steps Apply patterns in replit-core-workflow-a for real-world usage.