### Install and Run tweb Development Server
Source: https://github.com/morethanwords/tweb/blob/master/CLAUDE.md
Standard commands for installing dependencies, starting the development server, building for production, and running linters.
```bash
pnpm install
pnpm start # Dev server on :8080
pnpm build # Production build → dist/
pnpm test # Run tests (Vitest)
pnpm lint # ESLint on src/**/*.ts
```
--------------------------------
### Install Dependencies and Run Commands
Source: https://context7.com/morethanwords/tweb/llms.txt
Install dependencies using pnpm, start the dev server, build for production, run tests, or lint the code. Debug flags can be appended to the URL as query parameters.
```bash
pnpm install
pnpm start
pnpm build
pnpm test
pnpm lint
# Debug flags (append to URL as query params)
# ?test=1 → use Telegram test DCs
# ?debug=1 → verbose logging
# ?noSharedWorker=1 → disable SharedWorker (useful for debugging in one tab)
# ?http=1 → force HTTPS transport instead of WebSocket
```
--------------------------------
### Start Development Web Server
Source: https://github.com/morethanwords/tweb/blob/master/README.md
Run this command to start the local development server with live reloading. Access the application at http://localhost:8080/.
```bash
pnpm start
```
--------------------------------
### Start Snapshot Server App
Source: https://github.com/morethanwords/tweb/blob/master/snapshot-server/README.md
Navigate to the snapshot server directory and start the application. Ensure the port matches your development port or omit it to use the default.
```sh
cd ./snapshot-server
pnpm start --port=8080
```
--------------------------------
### Install Dependencies with pnpm
Source: https://github.com/morethanwords/tweb/blob/master/README.md
Use this command to install all necessary project dependencies before developing. Ensure pnpm is installed globally.
```bash
pnpm install
```
--------------------------------
### Snapshot Server for Local Storage Debugging
Source: https://context7.com/morethanwords/tweb/llms.txt
Instructions for starting the snapshot server and using browser console commands to capture and load IndexedDB/localStorage state for debugging.
```bash
# Start snapshot server (from project root)
node snapshot-server/server.js
# → runs on http://localhost:2000
# In browser dev console on http://localhost:8080:
# Take snapshot and download
window.__snapshot?.takeSnapshot();
# Load snapshot file back into the app
window.__snapshot?.loadSnapshot(snapshotFile);
# Useful for reproducing bugs from a specific state
# without needing to recreate a conversation manually
```
--------------------------------
### Take Local Storage Snapshot
Source: https://context7.com/morethanwords/tweb/llms.txt
Generate a snapshot of the local storage. This functionality requires the snapshot server to be running. Refer to `snapshot-server/README.md` for detailed setup instructions.
```javascript
// Take local storage snapshot (if snapshot server is running)
// See snapshot-server/README.md for details
```
--------------------------------
### Docker: Install Dependencies
Source: https://github.com/morethanwords/tweb/blob/master/README.md
Use this Docker Compose command to install dependencies within a containerized environment for development.
```bash
docker-compose up tweb.dependencies
```
--------------------------------
### Docker: Run Development Container
Source: https://github.com/morethanwords/tweb/blob/master/README.md
This command starts the development container using Docker Compose. Access the application at http://localhost:8080/.
```bash
docker-compose up tweb.develop
```
--------------------------------
### Popup Event Listener Setup
Source: https://github.com/morethanwords/tweb/blob/master/CODE_DUPLICATIONS.md
Standard pattern for adding event listeners within popup elements. Ensure `listenerSetter` and `addEventListener` are correctly implemented in the base class.
```typescript
this.listenerSetter.add(element)('click', callback);
this.addEventListener('show', () => { /* setup */ });
this.addEventListener('closeAfterTimeout', () => { /* cleanup */ });
```
--------------------------------
### Solid.js Component with Class Composition
Source: https://github.com/morethanwords/tweb/blob/master/CLAUDE.md
Example of a Solid.js component using the `classNames` helper for dynamic class attribute management. Ensure the `classNames` helper is imported from `@helpers/string/classNames`.
```typescript
import {JSX}
import classNames from '@helpers/string/classNames';
export default function MyComponent(props: {
class?: string,
children: JSX.Element
}) {
return (
{props.children}
);
}
```
--------------------------------
### Extend AppManager for Business Logic
Source: https://github.com/morethanwords/tweb/blob/master/CLAUDE.md
An example of extending the AppManager class to implement specific business logic within the application. It shows how to hook into lifecycle methods like `after` for initialization and interact with other managers.
```typescript
import {AppManager} from '@appManagers/manager';
export class AppSomethingManager extends AppManager {
protected after() {
// Initialization after state loaded
this.apiUpdatesManager.addMultipleEventsListeners({...});
}
}
```
--------------------------------
### Build Production Version
Source: https://github.com/morethanwords/tweb/blob/master/README.md
Execute this command to create a minimized production build of the application. The output will be in the 'public' folder, ready to be copied to a web server.
```bash
node build
```
--------------------------------
### Get All Entries from IndexedDB Store
Source: https://github.com/morethanwords/tweb/blob/master/snapshot-server/public/index.html
Retrieves all key-value pairs from a given IndexedDB object store using a cursor.
```javascript
function getAllEntries(store) {
return new Promise((resolve, reject) => {
const entries = [];
const request = store.openCursor();
request.onsuccess = (event) => {
const cursor = event.target.result;
if(cursor) {
entries.push({key: cursor.key, value: cursor.value});
cursor.continue();
} else {
resolve(entries);
}
};
request.onerror = () => reject(request.error);
});
}
```
--------------------------------
### Docker: Build Production Image
Source: https://github.com/morethanwords/tweb/blob/master/README.md
Build a production-ready Docker image for your application. Replace placeholders with your Docker Hub username and desired image name.
```bash
docker build -f ./.docker/Dockerfile_production -t {dockerhub-username}/{imageName}:{latest} .
```
--------------------------------
### Subscribe, Dispatch, and Access Managers with rootScope
Source: https://context7.com/morethanwords/tweb/llms.txt
Demonstrates how to subscribe to and dispatch events using the global `rootScope` event bus. Also shows how to access application managers and global state properties. Ensure `rootScope` is imported before use.
```typescript
import rootScope from '@lib/rootScope';
import {BroadcastEvents} from '@lib/rootScope';
// --- Subscribe to events ---
rootScope.addEventListener('user_auth', ({id}) => {
console.log('Logged in as', id);
});
rootScope.addEventListener('premium_toggle', (isPremium: boolean) => {
console.log('Premium status changed:', isPremium);
});
// Listen once
rootScope.addEventListener('managers_ready', () => {
console.log('All managers initialized');
}, {once: true});
// Remove listener
const handler = (chatId: ChatId) => console.log('Chat updated', chatId)
rootScope.addEventListener('chat_update', handler);
rootScope.removeEventListener('chat_update', handler);
// --- Dispatch events (from inside managers only) ---
rootScope.dispatchEvent('settings_updated', {
key: 'notifications.sound',
value: true,
settings: rootScope.settings
});
// Dispatch without re-broadcasting to worker (single-tab only)
rootScope.dispatchEventSingle('theme_changed');
// --- Access managers (all methods return Promise) ---
const chat = await rootScope.managers.appChatsManager.getChat(chatId);
const user = await rootScope.managers.appUsersManager.getUser(userId);
// --- Global state properties ---
rootScope.myId // current user's PeerId (NULL_PEERID before login)
rootScope.premium // boolean: current user has Telegram Premium
rootScope.settings // StateSettings snapshot (synced from manager)
// Full list of typed broadcast events (key → payload):
// 'chat_update' → ChatId
// 'user_auth' → UserAuth
// 'history_append' → {storageKey, message}
// 'message_sent' → {storageKey, tempId, mid, message}
// 'peer_typings' → {peerId, typings}
// 'connection_status_change' → ConnectionStatusChange
// 'premium_toggle' → boolean
// 'story_new' → {peerId, story, cacheType, maxReadId}
// 'stars_balance' → {balance, ton}
// ... (60+ events total, see BroadcastEvents in rootScope.ts)
```
--------------------------------
### Prefix Git Commands with rtk for Optimization
Source: https://github.com/morethanwords/tweb/blob/master/CLAUDE.md
Demonstrates the correct usage of RTK by prefixing Git commands to leverage token optimization. Incorrect usage without the prefix is also shown.
```bash
# ❌ Wrong
git add . && git commit -m "msg" && git push
# ✅ Correct
rtk git add . && rtk git commit -m "msg" && rtk git push
```
--------------------------------
### Docker Deployment Commands
Source: https://context7.com/morethanwords/tweb/llms.txt
Provides commands for setting up development and production environments using Docker Compose, and building standalone production images.
```bash
# Development (docker-compose)
docker-compose up tweb.dependencies # install node_modules
docker-compose up tweb.develop # dev server on :8080
# → Open http://localhost:8080/
# Production (docker-compose)
docker-compose up tweb.production -d # nginx serving built assets on :80
# → Open http://localhost/
# Standalone production image build
docker build \
-f ./.docker/Dockerfile_production \
-t myuser/tweb:latest \
.
# Run with custom API credentials
docker run -d -p 80:80 \
-e VITE_API_ID=YOUR_API_ID \
-e VITE_API_HASH=YOUR_API_HASH \
myuser/tweb:latest
```
--------------------------------
### Get User and Contacts with AppUsersManager
Source: https://context7.com/morethanwords/tweb/llms.txt
Retrieve user information, manage contacts, and search for users by name. Ensure the user is logged in to access synchronous properties like `myId`.
```typescript
const managers = rootScope.managers;
// Get a user object
const user = await managers.appUsersManager.getUser(userId); // User.user
// Get current user's ID
const myId = rootScope.myId; // PeerId (available synchronously after login)
// Get contacts list
const contacts = await managers.appUsersManager.getContacts('');
// Search contacts by name
const results = await managers.appUsersManager.getContacts('Alice');
// Resolve a username to a peer
const resolved = await managers.appPeersManager.resolveUsername('telegram');
// resolved: { peerId: PeerId, peer: User | Chat }
// Get top peers (frequently messaged)
const topPeers = await managers.appUsersManager.getTopPeers('correspondents');
// returns: MyTopPeer[] = {id: PeerId, rating: number}[]
// Block / unblock a user
await managers.appPrivacyManager.setPrivacy('inputPrivacyKeyStatusTimestamp', [
{_: 'inputPrivacyValueDisallowUsers', users: [userInput]}
]);
// Check if can message a user
const canMessage = await managers.appUsersManager.canSendToUser(userId);
```
--------------------------------
### Compact Infrastructure Commands
Source: https://github.com/morethanwords/tweb/blob/master/CLAUDE.md
RTK streamlines infrastructure command outputs for Docker and kubectl, providing compact lists and deduplicated logs with substantial token savings.
```bash
rtk docker ps # Compact container list
rtk docker images # Compact image list
rtk docker logs # Deduplicated logs
rtk kubectl get # Compact resource list
rtk kubectl logs # Deduplicated pod logs
```
--------------------------------
### Get All Entries from IndexedDB Store
Source: https://github.com/morethanwords/tweb/blob/master/public/snapshot.html
Retrieves all key-value pairs from an IndexedDB object store. This function returns a promise that resolves with an array of entries, where each entry is an object containing the key and value.
```javascript
function getAllEntries(store) { return new Promise((resolve, reject) => { const entries = []; const request = store.openCursor(); request.onsuccess = (event) => { const cursor = event.target.result; if(cursor) { entries.push({key: cursor.key, value: cursor.value}); cursor.continue(); } else { resolve(entries); } }; request.onerror = () => reject(request.error); }); }
```
--------------------------------
### Cache with Expiration Implementation
Source: https://github.com/morethanwords/tweb/blob/master/CODE_DUPLICATIONS.md
A cache implementation that stores values and their expiration times. The `get` method checks if the cached value is still valid before returning it, otherwise it fetches and caches a new value.
```typescript
private cache: {[id: string]: CachedType} = {};
private expiration: {[peerId: PeerId]: number} = {};
public get(id) {
if(this.cache[id] && Date.now() < this.expiration[id.toPeerId()]) {
return this.cache[id];
}
return this.fetchAndCache(id);
}
```
--------------------------------
### Enable Test DCs
Source: https://github.com/morethanwords/tweb/blob/master/README.md
Append `?test=1` to the URL to utilize test data centers for debugging or testing purposes.
```bash
http://localhost:8080/?test=1
```
--------------------------------
### Run All Project Tests
Source: https://github.com/morethanwords/tweb/blob/master/CLAUDE.md
Command to execute all tests within the project using pnpm.
```bash
pnpm test
```
--------------------------------
### Path Aliases in Vite Configuration
Source: https://context7.com/morethanwords/tweb/llms.txt
Source imports use path aliases defined in vite.config.ts for cleaner module resolution. This example shows common aliases and how to import MTProto types and local modules.
```typescript
// vite.config.ts alias table (automatically resolved at build time)
// @components → src/components/
// @helpers → src/helpers/
// @hooks → src/hooks/
// @stores → src/stores/
// @lib → src/lib/
// @appManagers → src/lib/appManagers/
// @environment → src/environment/
// @config → src/config/
// @vendor → src/vendor/
// @layer → src/layer.d.ts (MTProto API types, auto-generated 664KB)
// @types → src/types.d.ts
// @/* → src/
// solid-js → src/vendor/solid (custom fork)
import {Message, Chat, User, InputPeer} from '@layer'; // MTProto types
import rootScope from '@lib/rootScope'; // global event bus
import classNames from '@helpers/string/classNames'; // class composition
import {usePeer} from '@stores/peers'; // reactive peer store
```
--------------------------------
### Compact JavaScript/TypeScript Tooling Commands
Source: https://github.com/morethanwords/tweb/blob/master/CLAUDE.md
Optimize output for JavaScript and TypeScript package managers like pnpm, npm, and npx, as well as Prisma, with RTK for significant token reduction.
```bash
rtk pnpm list # Compact dependency tree (70%)
rtk pnpm outdated # Compact outdated packages (80%)
rtk pnpm install # Compact install output (90%)
rtk npm run