Document: WM-090 P. Webb
Category: Self-Host 2026-04-27
The beauty of creating your own tools
Abstract
Being the change you wish to see in the world, software-style.
Body
Late last week I was hit with a sudden need to update my GraphQL
module with QoL improvements and see if it was possible to create a
GraphiQL interface with Svelte so I could use that instead of the
React one embedded within (my module was a fork and I didn’t know
enough to swap it out). I won’t bury the lede, both projects are live
and work wonderfully. I’m so excited, check ’em out!
- @eol/gq[1]
- I intend to publish most (if not all) I build for EOL, my future
git forge/Github replacement. Glad I obtained this namespace
on JSR!
- View source[2]
- @eeeooolll/graphiql[3]
- I prefer Deno but JSR doesn’t understand .svelte files so I had
to use NPM
- Someone snagged @eol so I had to use the obnoxious-looking
@eeeooolll namespace
- View source[4]
## @eol/gq
When I was doing exploratory work on my personal OS concept, I
rethought how I build GraphQL servers and added some niceties to my
template. Here’s how I typically set them up:
For a directory listing like
schema
├─ api.graphql
├─ channel.graphql
├─ comment.graphql
├─ customer.graphql
├─ error.graphql
├─ guide.graphql
├─ login.graphql
├─ notification.graphql
├─ pagination.graphql
├─ playlist.graphql
├─ reaction.graphql
├─ report.graphql
├─ schema.graphql
├─ session.graphql
├─ stream.graphql
├─ subscription.graphql
├─ tag.graphql
└─ video.graphql
I would also have this in my schema.graphql
# import from "api.graphql"
# import from "channel.graphql"
# import from "comment.graphql"
# import from "customer.graphql"
# import from "error.graphql"
# import from "guide.graphql"
# import from "login.graphql"
# import from "notification.graphql"
# import from "pagination.graphql"
# import from "playlist.graphql"
# import from "reaction.graphql"
# import from "report.graphql"
# import from "session.graphql"
# import from "stream.graphql"
# import from "subscription.graphql"
# import from "tag.graphql"
# import from "video.graphql"
Each SDL in those files would get combined into the full schema. This
is way too much work. Why was I doing this?!
In my new setup I look for a # DYNAMIC_IMPORTS comment and the
module automatically looks for other .graphql files. If they’re in
the directory, you must want to use them, right? That was the first
QoL update.
The second was exporting makeExecutableSchema from
@graphql-tools/schema so I wouldn’t have to install a second
dependency that I always need anyway. SMH
I also ran into an issue a while back where TypeScript was
complaining about two versions of graphql because of my original
module was using an old version.
I wasn’t content with these updates though. Why not go further?!
If you wanna take a break and check out the new hotness, open your
Terminal and:
deno run -A https://code.webb.page/eol/gq.git/plain/remote-example.ts
Assuming you have Deno installed (curl the URL to check contents).
## @eeeooolll/graphiql
I asked Claude about the feasibility of replacing React in GraphiQL
with Svelte and it referenced a forum post from 2020 where someone
was asking for help doing that very same thing. This sounded familiar
so I checked it out and…yup, that was me[5].
Claude did a good job scaffolding and I spent the rest of the weekend
redesigning and customizing to my specifications.
Here, have some screenshots!
I even made the UI responsive! Not sure why you’d ever want to input
GraphQL queries on the go but whatevs.
When I’m coding or dealing with a Terminal, I prefer the block cursor
so after some trial and error I asked Claude for help and now we
have this!
It’s not perfect but I didn’t want to delve too deep into the
over-engineering threshold. Here’s how it works though:
const blockCaretTheme = EditorView.theme({
"&": {
caretColor: "transparent"
},
"& .cm-cursor": {
borderLeftColor: color("blue", 5),
borderLeftStyle: "solid",
borderLeftWidth: "1ch",
marginLeft: "0"
},
"& .cm-cursorLayer": {
mixBlendMode: "hard-light",
zIndex: "auto"
},
"& .cm-scroller": {
isolation: "isolate"
}
});
I’ve seen people try and guess the width of a character to make their
block cursors the perfect size when they could’ve just used 1ch in
CSS (I just learned about that this year, haha)!
You’ll also need @codemirror/view’s drawSelection if you go this
route, the rest of this code is here[6] (featuring the new uchū
NPM module)!
## @inc/uchu
I’ve long resisted making an NPM module for uchū because I was
convinced that I was done with them. Bun is fantastic, Deno is even
better, why do I need them? Well, Deno isn’t the best for everything
so here we are.
The work I was doing on those GraphQL modules necessitated the need
for an easy way to integrate my color palette and I made things as
easy as possible while cutting down on boilerplate and repeating
myself through code.
Find it on NPM[7] and my codex[8]!
## FIN
I was having a conversation with some online friends on Discord where
we lamented the immense lack of care and craft in software these
days. It seems like lots of people are using LLMs as an excuse to not
think[9] about things like safety, security, and taste.
There was a story where a startup used an LLM IN PRODUCTION AND GOT
THEIR DATABASE WIPED[10]. Like…what the actual fuck?! People are
insane. Imagine placing blame anywhere but yourself! SMDH
Anyhoo, I don’t trust "AI" tools as far as I can throw ’em and they
aren’t tangible so I can’t throw anything so why trust them??? I
intentionally use "LLM" because that’s true to what these tools ARE.
And AS tools they’re pretty damn good at helping me make tools for
the things I want to do.
There’s now documented proof that I’ve been railing against the tech
industry’s obsession with/reliance on React for more than half a
decade at least; it’s wack af. React Native isn’t a good excuse
anymore when excellent tools like Tauri[11] and Electrobun[12] exist.
Look at this guy, disgusted with the slowness of DuckDuckGo so he
replicated their !bangs feature and released a lil’ service[13] for
others to use. Pretty sweet.
All this to say, making your own tools is fun and awesome and I enjoy
the process. 🕸️