
Making free and open source web community software
May 12, 2022 – updated Jul 23, 2023
I've been making free and open source web community software with
Hamilton Reed full-time
since April 2021. (he's
@greatbacon on GitHub and
Mastodon) We've been working quietly in public
and leaving a trail of informal documentation through
GitHub PRs. We'll announce when we
reach alpha in Q3 2023.
Hamilton and I first met in December 2019 and started self-funded part-time work on what would become @feltjs. One of the main ideas was to make tools to help people be creative together - visit felt.dev to see where we are.
Our main project is felt-server, an extensible Node.js server and web frontend described as "a programmable platform for hobbyists and human-scale communities". The main UI looks like Discord and Slack on the surface, and it has aspects of a content management system and knowledge management software in a collaborative environment. We're aiming for a batteries-included, deeply customizable experience with a small footprint, that feels familiar and surprisingly powerful. Calling it a "programmable platform" is the best we have right now.
felt-server targets a specific UX. Instead of trying to replace any of today's large platforms, we think of felt-server as filling a niche that venture-funded startups and other commercial interests rationally ignore.
- it's made by and for devs, students, hobbyists, selfhosters, tinkerers, techies, lazy automation-enjoyers - it should give you all the control you want, be broadly useful, and remain a relatively simple project that's easy and cheap to self-host
- designed for small groups - scaling to thousands of people is less important for feltjs than the depth of interaction and richness of capabilities
- multipurpose, extensible, and interoperable, so the same toolkit can be used for many kinds of communities and websites and problems - felt-server can run some of your friendly bots in the clouds with a nice web GUI
- is free and open source with a documented API, and it's designed for fullstack customization, which means devs and end-users have proper access and power over their UX and systems and code, and we bridge more of the gap between programming and using
Fullstack customization is part of the point of feltjs, but today it's a vague idea with some interesting glimmers scattered around. The point is to help us solve problems, which are unknown and numerous, so we design the system holistcally with that in mind - the UX is the DX is the UX. It's confusing but so is the problem of solving so many problems.
For devs, this means we'll have open source servers, clients, and modules that are designed to be extended and plugged and swapped. It also means our programming vocabulary is exposed in the UX, so the system itself is more visible and directly interactive, blurring lines between the experiences of devs and end-users.
For end-users it means:
- a comfortable environment that looks like existing social apps, but when you go digging you find it's deeply customizable and flexible, and now it makes sense that people say all these seemingly different web experiences were "made with feltjs" and maybe you could use it to make that thing?
- a user-friendly text language - like Slack and Discord it'll be similar to Markdown - with access to a rich vocabulary that can be used to write chat messages, blog posts, forum replies, todo items, and so on, and also construct both social spaces and the entire client UI, forming the base of an accessible experience to design and share UI
- easy-to-use plugins/mods/applets made by both feltjs and hopefully a community of developer-users, with clear paths to learning the technical skills to make your own stuff - making an idea with code should be reduced to the essentials, so you incur no complexity beyond what's needed
- integration of low-level systems with high-level UX, so power users can go deep - things like integrated interactive documentation, a contextmenu UI pattern that enables direct interaction with everything you see, and recording events and authoring scripts and then composing them, like with governance processes (e.g. "execute this script if the vote passes")
Instead of being limited to filling digital boxes designed by tech companies, we could be designing own boxes for our unique situations and sharing the patterns with each other. I want the act of creating tools and sharing them to be a normal part of the software-using experience. One of the ways I think about feltjs is that it's a layer that sits between SvelteKit and your app, that's trying to do as much of the uninteresting parts as possible. You're the person with ideas, the tools should be enabling and out of the way.
felt-server will support simple and scalable static web publishing like blogs and RSS/Atom feeds, and also provide tools to make realtime social experiences and games that inherit your social context, enabling beginners to participate in the creative process more easily. Doing a hard thing is much easier when the task is reduced to its essentials.
We have a handful of software repos:
- @feltjs/felt-server – a programmable platform for hobbyists and human-scale communities, the Node.js server that's selfhostable and available as a library on npm
- @fuz.dev/fuz – styles and UI components for Svelte and SvelteKit 💚
- @feltjs/felt-template – a static web app template with SvelteKit, TypeScript, and Felt for quickly creating new projects - in the future it will support quickly creating a custom server project, too.
- @grogarden/util – JS utilities to complement the modern web platform 🦕🐋
- @feltjs/gro – a toolkit that extends SvelteKit and Vite with things we find useful for making web apps - it's used by all of our other projects
With feltjs, I hope we can make the role of toolmaker more accessible to more people on the web, to help us bring ideas to life while supporting beneficial relationships with technology. I like feltjs' combination of solid technical foundations, lightweight implementation, and DIY hackability. It's been fun and there's cooler stuff ahead.
Find us
P.S.
I'm having difficulty summarizing the project, it's big and there are many unknowns. The ideas below seem important to include but not that important, and you may not be the right audience. Thanks for reading.
Business and ownership
We haven't done the legal work to make it official, but the feltjs trademarks and domains, like the green heart logo and felt.dev, will be owned and managed by some kind of nonprofit entity. This is a commitment to the public open source community that these are community assets.
Originally I thought I was going to operate a hosting company, felt.social, so we could earn money and make software sustainably. The logic is air-tight - we're making selfhostable software, but not everyone wants to self-host, so we offer it for a fee, do what we love, and make open source sustainable, all in one move.
It sounded like a plan, except I don't love operations, not enough to take on the responsibilities for admin, moderation, holding keys, security, uptime, abuse, legal/international/etc. Also, the length of my todo list for software development is infinite, and taking a second job of this complexity does not seem productive. I feel significant pressures from the software side, so even if coworkers do most of the labor, I don't think I'll be able to sleep well at night if I'm one of the people responsible for your critical personal data not catching fire at all times. I'm going to spend my time making software instead of running a hosting company, and I'll gladly pay money to operators for hosting.
While my plan for financial sustainbility pivots to adjust to reality, Hamilton may continue developing felt.social as a cooperatively-owned host. Now he'll just need 4 cofounders instead of 3 to officially start the co-op in Colorado. Please take my money!!
Sharing spaces with others
One aspect of community software that's full of interesting opportunities is how to govern shared spaces - things like exercising power, communicating and enforcing rules, nudging norms, making collective decisions, scripting governance processes over time, and so on. Each group of people has distinct needs. I wrote about modeling social spaces in my second blog post.
For part of 2021 and 2022 Hamilton and I collaborated with PhD candidate Jane Im (imjane.net) on designs related to research-backed user-driven governance. Her paper "Yes: Affirmative Consent as a Theoretical Framework for Understanding and Imagining Social Platforms" (consentful.systems), which credits The Consentful Tech Project, has been a major source of inspiration for how we think about designing software, and motivated our Consentful Onboarding Sketch.
Our perspective as toolmakers is that we'll attempt to support all the things people want to do, from traditional moderator setups to democratic control and much more, and provide templates and guidance to help communities achieve their goals. We'll give this a lot of attention before beta, but I suspect the good stuff is years away, maybe using standards that Metagov is developing. I'm also following related projects CommunityRule and PolicyKit.
Tech notes
We tried to be thoughtful about our tech stack to be friendly to beginners without compromising on the delivered UX.
on the shoulders of giants on the backs of turtles
We chose the web because we think it's the best way to deliver the UX we want to the most people, and we chose JS, Node.js, and npm because of fit, familiarity, and productivity. The web is everywhere and has a lot of unrealized potential. In combination, Node.js, Postgres, nginx, and Linux are all productive and capable of delivering a good UX. TypeScript, Svelte, SvelteKit, and Vite are excellent for making robust and snappy UIs.
Our server-side code is written for Node.js today, but we should be able to offer significant runtime flexibility in the long term, largely thanks to SvelteKit, so you may choose Deno, Bun, a cloud platform's serverless offerings, or whatever else is in the Node.js legacy compat space. We're trying to minimize our exposure to Node-specific APIs to keep portability high. Node.js a practical choice, not an idealized one. (and we try to move forward - for example feltjs never used any CommonJS)
customizable and extensible
Both the server and clients are open source and our APIs are open, so clients can be modified with low friction or created from scratch. (our client will be decoupled from the server during alpha, stay tuned) We use TypeScript and Svelte across the full stack, and we try to leverage the benefits of integration when available, like sharing types, helpers, and schemas. We try to maximize the freedoms and degrees of freedom enjoyed by our users and developers, but security and performance are unfortunate constraints and sometimes buzzkills :\
Our client has a thickness optimized for a powerful and low-latency UX over long sessions, which means a lot of JS and client-side caching, and thanks to SvelteKit we should be able to deliver good experiences in many cases with fast loadtimes and minimal or zero JS. (but we're not there yet)
scaling (and not)
Our focus on "small communities" relates to a potentially deflating fact about our software - it doesn't scale to large numbers of people or some kinds of heavy load. felt-server can't be the best solution to all problems, so we make tradeoffs intentionally to serve a particular UX.
- quickly iterate on social experiences with human-scale groups of people
- on a single machine, running a server and local database with light resource requirements
- with web tech, putting us in a particular ecosystem of software
The limits may appear restrictive compared to the infinite cloud worlds that can host a global social network, but these choices give us a highly productive environment with low resource usage that's friendly to beginners. We're trying to be powerful in the small, and maybe small communities are good too.
We should be able to support non-realtime usecases that scale to more users like blogs and similar web publishing, much for free thanks to SvelteKit. We're prioritizing flexibility and UX over the ability to handle massive numbers of concurrent users or big data, and we'll improve various kinds of scaling over time.
interop and decentralization
I value giving users choices, and that includes cooperative interoperability, but we're a 2 person team with limited resources trying to deliver a specific UX. Today this means we have a centralized Node server with a lot of homemade solutions. One of my medium-long term goals is to support at least one federated/decentralized standard like ActivityPub or Matrix.
In our data system, we're following the ActivityStreams vocabulary spec that's used in ActivityPub and Mastodon (and I made some unofficial docs), but we have our own client-server protocol that works over RESTful http and websockets using JSON-RPC 2.0. We also publish a JSON Schema with our vocabulary, including both data objects and actions. We could feasibly generate OpenAPI schemas from our source of truth, giving us greatly expanded access to existing tooling, but we have no plans for that yet.
We want to be good citizens of open standards, not just do our own thing detached from open ecosystems, but we have very specific ideas of what we want to build for small communities, and federated tech isn't optimal for today's goals. (if you link me xkcd 927 i swear)
Given felt-server's small-scale design and selfhostability, it may help to think of it as "polycentric", where each community or "hub" is a silo of self-governed data, and any particular instance hosts one or more hubs. In combination with clients that connect to multiple services, I think "decentralized" is an appropriate description, but not in the way some people want, for example where their identity isn't mediated by the hub. I don't think felt-server will reach its potential until it can federate with the wider world, especially for user identity.
I personally think decentralized technologies are the future and I want to move with the times. In any case, we need user interfaces that are decoupled from the underlying protocols, and feltjs wants to be as repurposable as it can be.