Highly ambitious ATProtocol AppView service and sdks
1# Getting Started 2 3Build your first AT Protocol app in minutes with the Slices CLI. 4 5## Quick Start 6 7### Install the CLI 8 9You'll need Deno installed first. Get it at [deno.com](https://deno.com/). 10 11```bash 12# Install from JSR 13deno install -g -A jsr:@slices/cli --name slices 14``` 15 16### Login to Slices 17 18Before creating a project, authenticate with your AT Protocol account: 19 20```bash 21slices login 22``` 23 24This will open a browser window where you can authorize the CLI with your AT 25Protocol handle. 26 27### Create Your Project 28 29```bash 30# Create a new project with automatic setup 31slices init my-vinyl-app 32 33# Or let us generate a name/domain for you 34slices init 35``` 36 37The `slices init` command does everything for you: 38 39- Creates a full-stack Deno app with OAuth authentication 40- Automatically creates a slice on the network 41- Sets up OAuth credentials 42- Pulls standard lexicons (including Bluesky profiles) 43- Generates a TypeScript SDK 44- Initializes a git repository 45 46### Start Developing 47 48```bash 49cd my-vinyl-app 50deno task dev 51``` 52 53Visit http://localhost:8080 and you're live! 54 55## What You Get 56 57The `slices init` command creates a production-ready app with: 58 59> More templates/examples coming soon (i.e. React, Expo, Astro, etc) 60 61### Full-Stack Deno Application 62 63- **Server-side rendering** with Preact and JSX 64- **OAuth authentication** with PKCE flow and automatic token refresh 65- **HTMX integration** for dynamic UI without complex JavaScript 66- **Tailwind CSS** for beautiful, responsive styling 67- **SQLite sessions** for secure session management 68- **Feature-based architecture** for scalable code organization 69 70### AT Protocol Integration 71 72- **Configured slice** with your own namespace 73- **Generated TypeScript SDK** from your lexicons 74- **Automatic sync** capabilities 75- **Real-time updates** via Jetstream 76 77### Development Experience 78 79- **Hot reload** in development 80- **Type safety** throughout 81- **Environment variables** pre-configured 82- **Git repository** initialized 83 84## Project Structure 85 86Here's what the generated project structure looks like: 87 88``` 89my-vinyl-app/ 90├── slices.json # Slice configuration 91├── .env # Your credentials (auto-generated) 92├── deno.json # Deno configuration 93├── lexicons/ # AT Protocol schemas 94│ ├── com/ 95│ │ └── recordcollector/ 96│ │ └── album.json 97│ └── app/ 98│ └── bsky/ 99│ └── actor/ 100│ └── profile.json 101└── src/ 102 ├── main.ts # Server entry point 103 ├── config.ts # App configuration 104 ├── generated_client.ts # Your TypeScript SDK 105 ├── routes/ # HTTP routes 106 ├── features/ # Feature modules 107 │ ├── auth/ # OAuth implementation 108 │ └── dashboard/ # Main app UI 109 ├── shared/ # Reusable components 110 └── utils/ # Helper functions 111``` 112 113## CLI Commands 114 115The Slices CLI is your command center: 116 117### Project Management 118 119```bash 120# Create a new project 121slices init my-app 122 123# Check your authentication status 124slices status 125 126# Authenticate with Slices network 127slices login 128``` 129 130### Lexicon Management 131 132```bash 133# Pull lexicons from your slice 134slices lexicon pull 135 136# Push local lexicons to your slice 137slices lexicon push 138 139# List lexicons in your slice 140slices lexicon list 141``` 142 143### Code Generation 144 145```bash 146# Generate TypeScript SDK from lexicons 147slices codegen 148 149# The SDK is created at src/generated_client.ts 150``` 151 152### Monitoring 153 154```bash 155# View real-time Jetstream logs 156slices logs 157 158# See sync activity and data flow 159slices logs --verbose 160``` 161 162## Working with Lexicons 163 164Lexicons define your data structure. The init command includes Bluesky profile 165lexicons to get you started, but you'll want to add your own custom lexicons for 166your app. 167 168### Modify an Existing Lexicon 169 170Edit `lexicons/com/recordcollector/album.json`: 171 172```json 173{ 174 "lexicon": 1, 175 "id": "com.recordcollector.album", 176 "defs": { 177 "main": { 178 "type": "record", 179 "description": "A vinyl album in my collection", 180 "record": { 181 "type": "object", 182 "required": ["title", "artist", "releaseDate"], 183 "properties": { 184 "title": { "type": "string" }, 185 "artist": { "type": "string" }, 186 "releaseDate": { 187 "type": "string", 188 "format": "datetime" 189 }, 190 "genre": { 191 "type": "array", 192 "items": { "type": "string" } 193 }, 194 "condition": { 195 "type": "string", 196 "enum": [ 197 "Mint", 198 "Near Mint", 199 "Very Good Plus", 200 "Very Good", 201 "Good", 202 "Fair", 203 "Poor" 204 ] 205 }, 206 "notes": { "type": "string" } 207 } 208 } 209 } 210 } 211} 212``` 213 214### Create a New Lexicon 215 216Create `lexicons/com/recordcollector/review.json`: 217 218```json 219{ 220 "lexicon": 1, 221 "id": "com.recordcollector.review", 222 "defs": { 223 "main": { 224 "type": "record", 225 "description": "Album review", 226 "record": { 227 "type": "object", 228 "required": ["albumUri", "rating", "content"], 229 "properties": { 230 "albumUri": { 231 "type": "string", 232 "format": "at-uri" 233 }, 234 "rating": { 235 "type": "integer", 236 "minimum": 1, 237 "maximum": 5 238 }, 239 "content": { "type": "string" }, 240 "createdAt": { 241 "type": "string", 242 "format": "datetime" 243 } 244 } 245 } 246 } 247 } 248} 249``` 250 251### Update Your Slice 252 253After modifying lexicons: 254 255```bash 256# Push changes to your slice 257slices lexicon push 258 259# Regenerate the TypeScript SDK 260slices codegen 261``` 262 263Your SDK at `src/generated_client.ts` now includes the new types and methods! 264 265**Important:** You must push your lexicons to the slice before you can create 266records. The slice needs to know about your schema in order to validate and 267store records. 268 269## Using the Generated SDK 270 271The generated SDK provides a type-safe client for your slice: 272 273```typescript 274import { AtprotoClient } from "./generated_client.ts"; 275 276// Initialize the client 277const client = new AtprotoClient({ 278 baseUrl: "https://api.slices.network", 279 sliceUri: Deno.env.get("SLICE_URI")!, 280}); 281 282// List albums with filtering and sorting 283const albums = await client.com.recordcollector.album.getRecords({ 284 where: { 285 genre: { contains: "jazz" }, 286 }, 287 sortBy: [{ field: "releaseDate", direction: "desc" }], 288 limit: 20, 289}); 290 291// Add a new album 292const newAlbum = await client.com.recordcollector.album.createRecord({ 293 title: "Kind of Blue", 294 artist: "Miles Davis", 295 releaseDate: "1959-08-17T00:00:00Z", 296 genre: ["jazz", "modal jazz"], 297 condition: "Near Mint", 298 notes: "Original Columbia pressing", 299}); 300 301// Get a specific album 302const album = await client.com.recordcollector.album.getRecord({ 303 uri: newAlbum.uri, 304}); 305 306// Update an album 307await client.com.recordcollector.album.updateRecord({ 308 uri: album.uri, 309 record: { 310 ...album.value, 311 notes: "Verified as first pressing!", 312 }, 313}); 314 315// Delete an album 316await client.com.recordcollector.album.deleteRecord({ 317 uri: album.uri, 318}); 319``` 320 321### External Collections 322 323Since the init command included Bluesky profile lexicons, your SDK has methods 324for querying them: 325 326```typescript 327// Query users by display name (from included Bluesky lexicons) 328const profiles = await client.app.bsky.actor.profile.getRecords({ 329 where: { 330 displayName: { contains: "vinyl collector" }, 331 }, 332}); 333``` 334 335Any record-type lexicon you add to your slice will generate corresponding SDK 336methods when you run `slices codegen`. 337 338## Syncing Data 339 340Once your app is running, you can sync data from the AT Protocol network. 341 342### User Authentication Sync 343 344When users log in via OAuth, you can sync their data using the 345`syncUserCollections` method. This discovers and imports their external 346collections (like Bluesky profiles and posts). 347 348```typescript 349// After user logs in 350await client.network.slices.slice.syncUserCollections(); 351``` 352 353### Manual Bulk Sync 354 355Use the web interface at https://slices.network to start a bulk sync job. 356Navigate to your slice's Sync tab to configure which collections and 357repositories to sync. 358 359**Note:** If you created new lexicons, you'll be the only one with records 360initially. As more users adopt your app and write records to their own PDSs, you 361can sync from their repositories to grow your network. 362 363### Real-time Updates 364 365Jetstream automatically tracks creates, updates, and deletes across the network: 366 367```bash 368# Monitor real-time sync 369slices logs --slice $SLICE_URI 370``` 371 372## Deployment 373 374Your app is ready for production deployment. 375 376### Deno Deploy 377 378Create a free account at [deno.com/deploy](https://deno.com/deploy). Push your 379code to GitHub, then connect your repository through the Deno Deploy dashboard 380to deploy your app. 381 382For production use with Deno Deploy, switch from SQLite to Deno KV for OAuth and 383session storage: 384 385```typescript 386import { DenoKVOAuthStorage } from "@slices/oauth"; 387import { DenoKVAdapter } from "@slices/session"; 388 389// Configure OAuth with Deno KV storage 390const oauthClient = new OAuthClient({ 391 clientId: Deno.env.get("OAUTH_CLIENT_ID")!, 392 clientSecret: Deno.env.get("OAUTH_CLIENT_SECRET")!, 393 authBaseUrl: Deno.env.get("OAUTH_AIP_BASE_URL")!, 394 redirectUri: Deno.env.get("OAUTH_REDIRECT_URI")!, 395 storage: new DenoKVOAuthStorage(), // Uses Deno KV 396}); 397 398// Configure sessions with Deno KV adapter 399const sessionStore = new SessionStore({ 400 adapter: new DenoKVAdapter(), // Uses Deno KV 401 cookieOptions: { 402 secure: true, 403 httpOnly: true, 404 }, 405}); 406``` 407 408Deno KV provides serverless-compatible storage that scales automatically with 409your deployment. 410 411## Manual Setup (Advanced) 412 413If you prefer to set things up manually or need custom configuration: 414 415### 1. Create a Slice via Web UI 416 417Visit https://slices.network and: 418 4191. Log in with your AT Protocol account 4202. Click "Create Slice" 4213. Choose your namespace (e.g., `com.recordcollector`) 422 423### 2. Create OAuth Credentials 424 425In your slice dashboard: 426 4271. Go to Settings → OAuth Clients 4282. Create a new client 4293. Set redirect URI: `http://localhost:8080/oauth/callback` 4304. Copy the Client ID and Secret 431 432### 3. Set Up Your Project 433 434Use any framework you prefer. You can use the generated TypeScript SDK (works 435with any JavaScript/TypeScript environment) or call the XRPC endpoints directly 436from any language: 437 438```bash 439# Configure environment 440cp .env.example .env 441# Edit .env with your credentials 442 443# Start your project 444# (commands depend on your framework choice) 445``` 446 447## Next Steps 448 449- [Core Concepts](./concepts.md): Understand slices, lexicons, sync, and code 450 generation 451- [API Reference](./api-reference.md): Detailed endpoint documentation 452- [SDK Usage](./sdk-usage.md): Advanced SDK patterns and examples 453- [Examples](./examples/): Sample applications and use cases 454 455## Need Help? 456 457- Join our [Discord community](https://discord.gg/slices) 458- Check out [example apps](https://github.com/slices/examples) 459- Read the [AT Protocol docs](https://atproto.com/) 460- Report issues on [Tangled](https://tangled.sh/slices.network/slices/issues)