Skip to content

neuezxc/playwithu

Repository files navigation

PlayWithU

An open-source AI character roleplay chat app β€” your own Character.AI alternative, running entirely in the browser.

Features β€’ Getting Started β€’ Architecture β€’ Customization β€’ Contributing


✨ What is PlayWithU?

PlayWithU is a privacy-first, client-side AI roleplay chat app that lets you create, customize, and chat with AI characters β€” all without a backend. Your data never leaves your browser.

Bring your own API key (via OpenRouter), pick any LLM, and start roleplaying. No sign-ups, no subscriptions, no data collection.


🎯 Features

πŸ’¬ Immersive Chat Interface

  • Real-time AI conversations with rich markdown rendering (bold, italics, code blocks)
  • Message editing β€” edit any user message and regenerate the AI response from that point
  • Response regeneration with candidate navigation β€” swipe through multiple AI responses for the same prompt
  • Message deletion β€” remove individual messages from chat history
  • Slash commands β€” /reset to start over, /characters to manage personas, /dbg for debug tools

🎭 Character Management

  • Create custom characters with name, avatar, bio, description, scenario, and first message
  • Dedicated character gallery at /characters with search, grid view, and active character indicator
  • Import / Export β€” share characters as JSON files or back up your entire collection
  • Default character included β€” start chatting immediately with the built-in persona

🧠 Memory & Summarization

  • AI-powered chat memory β€” automatically summarizes your conversation into a structured memory block (NPCs, places, relationships, lore, timeline)
  • Auto-summarize β€” triggers every 10 messages to keep context fresh without manual effort
  • Memory snapshots β€” save, restore, and manage up to 10 memory versions
  • Custom memory prompt β€” full control over how the AI structures its memory

✏️ Custom System Prompts

  • Dynamic placeholder system β€” use {{char}}, {{user}}, {{char_description}}, {{user_description}}, {{scenario}}, {{memory}}, and {{tools}} in your prompts
  • Create & manage multiple prompts β€” CRUD operations with the ability to switch between prompts on the fly
  • Live preview mode β€” see how placeholders resolve before sending to the API
  • Token counting β€” keep track of prompt size to stay within model limits

πŸ”§ Pattern Replacements (Tools)

  • Inject reusable prompt snippets into the {{tools}} placeholder
  • Toggle tools on/off per conversation without deleting them
  • Great for adding personality quirks, knowledge bases, or behavior rules dynamically

βš™οΈ API Configuration

  • OpenRouter integration β€” access hundreds of LLMs through a single API key
  • Model selection β€” use any model available on OpenRouter
  • Tunable parameters β€” temperature, max tokens, top-p, frequency penalty, presence penalty
  • One-click parameter reset to sensible defaults

πŸ› οΈ Developer Tools

  • Built-in debug modal (/dbg) β€” inspect API request/response logs in real time
  • Full request tracing β€” see exactly what's being sent to and received from the LLM

πŸ“± Other Highlights

  • Dark theme β€” sleek, modern UI built for extended sessions
  • Responsive design β€” works on desktop and mobile
  • Persistent state β€” all data saved to localStorage (survives page reloads)
  • Zero backend β€” no server, no database, no cloud β€” everything runs client-side

πŸš€ Getting Started

Prerequisites

Installation

# Clone the repository
git clone https://github.com/neuezxc/playwithu.git
cd playwithu

# Install dependencies
npm install

# Start the dev server (Turbopack)
npm run dev

Open http://localhost:3000 in your browser.

First-Time Setup

  1. Click the menu button (βš™οΈ) in the chat input area
  2. Open API Settings
  3. Paste your OpenRouter API key and set your preferred model ID
  4. Start chatting!

πŸ—οΈ Architecture

PlayWithU is a single-page Next.js 15 app (App Router) with no server components doing data fetching β€” everything is client-side.

app/
β”œβ”€β”€ page.js                    # Main chat page ("use client")
β”œβ”€β”€ layout.js                  # Root layout with Geist font
β”œβ”€β”€ globals.css                # Global styles + Tailwind v4
β”œβ”€β”€ characters/
β”‚   └── page.jsx               # Character gallery page
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ SuperInput.jsx         # Chat input with slash commands
β”‚   β”œβ”€β”€ InputMenu.jsx          # Settings menu buttons
β”‚   β”œβ”€β”€ chat/
β”‚   β”‚   β”œβ”€β”€ ChatList.jsx       # Message list with auto-scroll
β”‚   β”‚   β”œβ”€β”€ CharacterChat.jsx  # AI message bubble (with regen/navigate)
β”‚   β”‚   β”œβ”€β”€ UserChat.jsx       # User message bubble (with edit)
β”‚   β”‚   └── CharacterImagePopup.jsx  # Draggable character avatar
β”‚   └── modal/
β”‚       β”œβ”€β”€ ApiSettingsModal.jsx       # API key, model, parameters
β”‚       β”œβ”€β”€ CharacterModal.jsx         # Create/edit characters
β”‚       β”œβ”€β”€ CustomPromptModal.jsx      # System prompt editor
β”‚       β”œβ”€β”€ MemoryModal.jsx            # Memory & summarization
β”‚       β”œβ”€β”€ PatternReplacementModal.jsx # Tools / prompt snippets
β”‚       └── DebugModal.jsx             # API request inspector
β”œβ”€β”€ store/
β”‚   β”œβ”€β”€ useCharacterStore.js   # Characters, messages, pattern replacements
β”‚   β”œβ”€β”€ useApiSettingStore.js   # API key, model, generation params
β”‚   β”œβ”€β”€ usePromptStore.js       # System prompts (default + custom)
β”‚   β”œβ”€β”€ useMemoryStore.js       # Chat summarization & snapshots
β”‚   β”œβ”€β”€ useChatStore.js         # Message count tracking
β”‚   β”œβ”€β”€ useUserStore.js         # User name/description (non-persisted)
β”‚   └── useDebugStore.js        # Debug logs
└── utils/
    β”œβ”€β”€ replacerTemplate.js    # {{placeholder}} replacement engine
    β”œβ”€β”€ textFormatter.js       # Markdown/formatting utilities
    β”œβ”€β”€ textUtils.js           # Text helper functions
    └── formatChatForSummarize.js  # Chat β†’ summary formatter

Tech Stack

Layer Technology
Framework Next.js 15 (App Router, Turbopack)
UI React 19
Styling Tailwind CSS v4
State Zustand 5 (persisted to localStorage)
Icons Lucide React
Markdown react-markdown + rehype-raw
AI Provider OpenRouter API (client-side fetch)
Font Geist + Inter

State Management

All stores use Zustand with persist middleware (saved to localStorage), except useUserStore which resets on reload.

Store Key Purpose
useCharacterStore character-storage Active character, character list, messages, pattern replacements
useApiSettingStore api-storage API key, model ID, temperature, max_tokens, etc.
usePromptStore prompt-storage Default + custom system prompts
useMemoryStore memory-storage Summarization text, snapshots, memory prompt
useChatStore chat-storage Message count for auto-summarize triggers
useUserStore (not persisted) User name & description
useDebugStore (not persisted) API request/response logs

🎨 Customization

Creating a Character

Characters are defined with:

Field Description
Name The character's display name
Avatar URL Image URL for chat bubbles and gallery
Bio Short tagline shown in the character card
Description Detailed personality and appearance (supports {{user}} placeholders)
Scenario World-building context injected into the system prompt
First Message The opening message when a chat starts

Writing System Prompts

Use the Custom Prompt editor to write your own system prompts with dynamic placeholders:

You are roleplaying as {{char}}. The user is {{user}}.

{{char_description}}

Scenario: {{scenario}}

Memory: {{memory}}

Tools: {{tools}}

All placeholders are replaced with real values before the prompt is sent to the API.

Pattern Replacements (Tools)

Add reusable prompt snippets that get injected into {{tools}}:

  • Toggle them on/off per conversation
  • Great for adding situational rules, knowledge, or personality modifiers
  • Changes take effect immediately β€” the system prompt is refreshed on every toggle

πŸ§ͺ Commands

Command Action
/reset Clear chat history and memory, start fresh
/characters Navigate to the character gallery
/dbg Open the debug inspector modal

πŸ“¦ Scripts

npm run dev      # Start dev server (Turbopack)
npm run build    # Production build
npm run start    # Start production server
npm run lint     # Run ESLint

🀝 Contributing

Contributions are welcome! This is a JavaScript-only project (no TypeScript).

  1. Fork the repo
  2. Create a feature branch (git checkout -b feat/amazing-feature)
  3. Commit your changes (git commit -m 'feat: add amazing feature')
  4. Push to the branch (git push origin feat/amazing-feature)
  5. Open a Pull Request

Code Style

  • No semicolons (unless needed for disambiguation)
  • Single quotes for strings
  • 2-space indentation
  • === only, never ==
  • handleXxx naming for event handlers
  • Named exports for components

πŸ“„ License

This project is open source. See the repository for license details.


Built with ❀️ by neuezxc

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors