···11# skylite (pre alpha)
22an attempt to make a lightweight, easily self-hostable, scoped Bluesky appview
3344+(as of 28 aug 2025)
55+currently the state of the project is:
66+
77+
88+49this project uses:
510- live sync systems: [jetstream](https://github.com/bluesky-social/jetstream) and [spacedust](https://spacedust.microcosm.blue/)
611- backfill: [listRecords](https://docs.bsky.app/docs/api/com-atproto-repo-list-records) and [constellation](https://constellation.microcosm.blue/)
712- the backend server stuff: [sqlite](https://jsr.io/@db/sqlite) db, typescript with [codegen](https://www.npmjs.com/package/@atproto/lex-cli), and [deno](https://deno.com/)
813- frontend: still deno and esbuild and tailwind and react and jsx and typescript (was fun getting these to run on deno)
9141010-## Status
1111-(as of 27 aug 2025)
1212-currently the state of the project is:
1313-### Index Server
1414-- Database:
1515- - Works, though it still needs some more tuning and iteration
1616-- Registration:
1717- - not there yet. currently manually adding users
1818- - onboarding backfill is probably next maybe
1919- - got a fancy new ui (not finished)
2020-- Indexing:
2121- - Jetstream:
2222- - its there, i just need to actually handle each and every record type and insert it to the db (like currently 2 out of 12 or so record collections are being inserted into the db)
2323- - Spacedust:
2424- - its a backlink index so i only needed one table, and so it is complete
2525-- Server:
2626- - Initial implementation is done
2727- - uses per-user instantiation thing so it can add or remove users as needed
2828- - pagination is not a thing yet \:\(
2929- - does not implement the Ref / Partial routes yet (currently strips undefineds) (fixing this soon)
3030- - also implements the entirety of the Constellation API routes as a bonus (under `/links/`)
3131-- Lexicon:
3232- - unsure about PostViewRef's optional fields
3333- - theres 3 remaining profile-related routes thats still not defined yet
3434- - some routes need more tweaks
3535- - considering adding optional query params to request either skeleton only, partials, or full hydrated (might not be respected by the server though lol)
3636- - considering making all of the api routes custom instead of the current situation of having some of the Index server routes be the original unmodified bsky.app routes
3737-3838-### View Server
3939-- Registration:
4040- - got a fancy new ui (not finished)
4141- - no backfill yet
4242-- Bsky API Routes:
4343- - currently mostly just proxies api.bsky.app
4444- - Notifications works ! thanks to spacedust
4545- - Following feed is probably next
4646-- Database:
4747- - i havent split the DB between the Index server and View server yet
4848-- Hydration (resolving `Ref`s, handling partials):
4949- - It works! not implemented for all routes yet but it can find a route i think maybe idk
5050- - it does now have a ranking system to decide which index server to be prioritized if multiple index servers indexes the same user account. (and also supports both api sets (Bluesky AppView API (legacy/fallback) and Bluesky Index Server API ))
5151-5215## Running
5316this project is pre-alpha and not intended for general use yet. you are welcome to experiment if you dont mind errors or breaking changes.
5417···6326deno task index
6427```
6528it should just work actually
6666-implemented xrpc routes for `#skylite_index` are:
6767-```ts
6868-const indexServerRoutes = new Set([
6969- "/xrpc/app.bsky.actor.getProfile",
7070- "/xrpc/app.bsky.actor.getProfiles",
7171- "/xrpc/app.bsky.feed.getActorFeeds",
7272- "/xrpc/app.bsky.feed.getFeedGenerator",
7373- "/xrpc/app.bsky.feed.getFeedGenerators",
7474- "/xrpc/app.bsky.feed.getPosts",
7575- "/xrpc/party.whey.app.bsky.feed.getActorLikesPartial",
7676- "/xrpc/party.whey.app.bsky.feed.getAuthorFeedPartial",
7777- "/xrpc/party.whey.app.bsky.feed.getLikesPartial",
7878- "/xrpc/party.whey.app.bsky.feed.getPostThreadPartial",
7979- "/xrpc/party.whey.app.bsky.feed.getQuotesPartial",
8080- "/xrpc/party.whey.app.bsky.feed.getRepostedByPartial",
8181- // i havent implemented these three yet
8282- /*
8383- app.bsky.graph.getLists // doesnt need to because theres no items[], and its self ProfileViewBasic
8484- app.bsky.graph.getList // needs to be Partial-ed (items[] union with ProfileViewRef)
8585- app.bsky.graph.getActorStarterPacks // maybe doesnt need to be Partial-ed because its self ProfileViewBasic
8686- */
8787-8888- // and the last one is a stub because its pretty hard to do
8989- "/xrpc/party.whey.app.bsky.feed.getListFeedPartial",
9090-]);
9191-```
92299330there is no way to register users to be indexed by the server yet (either Index nor View servers) so you can just manually add your account to the `system.db` file for now
9431···10037expose your localhost to the web using a tunnel or something and use that url as the custom appview url
1013810239this should work on any bluesky client that supports changing the appview URL (im using an unreleased custom fork for development) as the view server implements the `#bsky_appview` routes for compatibility with existing clients
4040+4141+ive got a custom `social-app` fork here [https://github.com/rimar1337/social-app/tree/publicappview-colorable](https://github.com/rimar1337/social-app/tree/publicappview-colorable)
1034210443the view server has extra configurations that you need to understand.
10544the view server hydrates content by calling other servers (either an `#skylite_index` or `#bsky_appview`) and so you need to write the order of which servers are prioritized first for resolving the hydration endpoints