{
"path": "/3m2s77ba5m22n",
"site": "at://did:plc:fpruhuo22xkm5o7ttr2ktxdo/site.standard.publication/3m23dstduds2v",
"$type": "site.standard.document",
"title": "how to manage your AT Lexicons with lpm",
"content": {
"$type": "pub.leaflet.content",
"pages": [
{
"$type": "pub.leaflet.pages.linearDocument",
"blocks": [
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"index": {
"byteEnd": 64,
"byteStart": 56
},
"features": [
{
"$type": "pub.leaflet.richtext.facet#code"
}
]
}
],
"plaintext": "if you're writing an AT application you probably have a lexicons folder in your repo with all of your Lexicons in JSON."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [],
"plaintext": "it might look something like this"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"alt": "a tree view of lexicon/ folder with a bunch of json in it",
"$type": "pub.leaflet.blocks.image",
"image": {
"$type": "blob",
"ref": {
"$link": "bafkreihipol665tt6qznf23ehv2y654imiebolwk67xklojpeknj2ucvye"
},
"mimeType": "image/png",
"size": 526037
},
"aspectRatio": {
"width": 1954,
"height": 1202
}
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [],
"plaintext": "this is fine and it works but it's a bit annoying to keep them up to date or even to find them in the first place."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"index": {
"byteEnd": 19,
"byteStart": 8
},
"features": [
{
"uri": "https://bsky.app/profile/tom.sherman.is",
"$type": "pub.leaflet.richtext.facet#link"
}
]
},
{
"index": {
"byteEnd": 53,
"byteStart": 49
},
"features": [
{
"$type": "pub.leaflet.richtext.facet#bold"
}
]
}
],
"plaintext": "luckily Tom Sherman made a little utility called lpm that does this for you. it's prerelease software so maybe don't depend on it in \"production\" yet but i tried it and it seemed pretty solid."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [],
"plaintext": "here's how it works"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"index": {
"byteEnd": 25,
"byteStart": 21
},
"features": [
{
"uri": "https://github.com/lexicon-community/lpm/blob/main/packages/cli/README.md#%EF%B8%8F-experimental-nodejs-support",
"$type": "pub.leaflet.richtext.facet#link"
}
]
},
{
"index": {
"byteEnd": 33,
"byteStart": 29
},
"features": [
{
"uri": "https://github.com/lexicon-community/lpm/blob/main/packages/cli/README.md#install",
"$type": "pub.leaflet.richtext.facet#link"
}
]
}
],
"plaintext": "you install it (with Node or Deno) and then you can do"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.code",
"language": "shellscript",
"plaintext": "lpm add app.bsky.actor.defs\nlpm add \"com.atproto.repo.*\""
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"index": {
"byteEnd": 23,
"byteStart": 4
},
"features": [
{
"$type": "pub.leaflet.richtext.facet#code"
}
]
}
],
"plaintext": "(or npm run lpm add ... for Node users)"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [],
"plaintext": "it will do two things:"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"index": {
"byteEnd": 99,
"byteStart": 90
},
"features": [
{
"$type": "pub.leaflet.richtext.facet#code"
}
]
}
],
"plaintext": "1. resolve and download these external lexicons (and all of their dependencies) into your lexicons/ folder"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"index": {
"byteEnd": 20,
"byteStart": 7
},
"features": [
{
"$type": "pub.leaflet.richtext.facet#code"
}
]
}
],
"plaintext": "2. add lexicons.json with this list. for example, the above expanded to these (note transitive deps aren't listed here):"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.code",
"plaintext": "{\n \"lexicons\": [\n \"app.bsky.actor.defs\",\n \"com.atproto.repo.uploadBlob\",\n \"com.atproto.repo.strongRef\",\n \"com.atproto.repo.putRecord\",\n \"com.atproto.repo.listRecords\",\n \"com.atproto.repo.listMissingBlobs\",\n \"com.atproto.repo.importRepo\",\n \"com.atproto.repo.getRecord\",\n \"com.atproto.repo.describeRepo\",\n \"com.atproto.repo.deleteRecord\",\n \"com.atproto.repo.defs\",\n \"com.atproto.repo.createRecord\",\n \"com.atproto.repo.applyWrites\"\n ]\n}"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"index": {
"byteEnd": 72,
"byteStart": 63
},
"features": [
{
"$type": "pub.leaflet.richtext.facet#code"
}
]
}
],
"plaintext": "now whenever i want to fetch them based on this file, i can do lpm fetch them again."
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [],
"plaintext": "i think this is cool for three reasons:"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [],
"plaintext": "1. copy pasting json is kinda silly and it makes sense to have a package manager for that"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"index": {
"byteEnd": 36,
"byteStart": 18
},
"features": [
{
"uri": "https://atproto.com/specs/lexicon#lexicon-publication-and-resolution",
"$type": "pub.leaflet.richtext.facet#link"
}
]
},
{
"index": {
"byteEnd": 183,
"byteStart": 168
},
"features": [
{
"uri": "https://resolve-lexicon.pages.dev/",
"$type": "pub.leaflet.richtext.facet#link"
}
]
}
],
"plaintext": "2. this relies on Lexicon Resolution which hopefully will lead more of the community to publish their lexicons via DNS so they can be resolved with other tooling, like resolve-lexicon and equivalents"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [
{
"index": {
"byteEnd": 46,
"byteStart": 33
},
"features": [
{
"$type": "pub.leaflet.richtext.facet#code"
}
]
},
{
"index": {
"byteEnd": 194,
"byteStart": 187
},
"features": [
{
"uri": "https://tangled.org/@danabra.mov/typelex/issues/5",
"$type": "pub.leaflet.richtext.facet#link"
}
]
}
],
"plaintext": "3. other tools might start using lexicons.json as source of truth for \"which external lexicons are you depending on?\" which might be handy! for example i might rely on this convention in Typelex where i need to know which lexicons are being vendored in"
}
},
{
"$type": "pub.leaflet.pages.linearDocument#block",
"block": {
"$type": "pub.leaflet.blocks.text",
"facets": [],
"plaintext": "lpm is in an early phase right now but i think it's cool and i want more people to check it out. thank you for reading"
}
}
]
}
]
},
"bskyPostRef": {
"cid": "bafyreids5oq37fdsvl7pjx2prxbyuan3qu2qvwfaw4znifdknqkgldx6ke",
"uri": "at://did:plc:fpruhuo22xkm5o7ttr2ktxdo/app.bsky.feed.post/3m2s77glvp22n",
"commit": {
"cid": "bafyreibszkdfemifhafvia273biu2sfmvxcxv36mbp2kkk7nqw35wusffi",
"rev": "3m2s77gp7wr27"
},
"validationStatus": "valid"
},
"description": "",
"publishedAt": "2025-10-09T22:26:22.184Z"
}