This release is a pre-release and may not be stable for production use.
feedwell
"All social media clients suck. This one just sucks less." —aclark4life, 2026.
A unified, local-first client for your social media feeds — one place to read and interact with everything, instead of juggling a pile of terrible individual apps.
Install
pip install feedwell
Requires a running MongoDB instance. Point feedwell at it with the
MONGODB_URI environment variable (defaults to mongodb://localhost:27017/).
For local development without installing MongoDB yourself, you can use mongodb-runner:
npx mongodb-runner start --id feedwell-dev
# note the printed connection string, then:
export MONGODB_URI="mongodb://127.0.0.1:<port>/"
Run
feedwell
This runs migrations, starts a local dev server, and opens it in your
browser. feedwell <command> also forwards to Django's manage.py, e.g.
feedwell createsuperuser.
Stack
Built with Django and django-mongodb-backend, so posts and their platform-specific metadata (metrics, media) can be stored as embedded documents instead of forced into rigid relational tables.
Using as a reusable Django app
Another Django project can also use feedwell's reusable feeds app instead of
the standalone feedwell CLI layer:
pip install feedwell
Requirements in the consuming project:
django_mongodb_backendinINSTALLED_APPSDATABASES["default"]["ENGINE"] = "django_mongodb_backend"- MongoDB as the backing database
AUTH_USER_MODELconfigured (any user model works;feedwell.feeds.models.AccountusesForeignKey(settings.AUTH_USER_MODEL, ...))- A MongoDB-compatible
DEFAULT_AUTO_FIELD, for exampledjango_mongodb_backend.fields.ObjectIdAutoField(matchingfeedwell.feeds.apps.FeedsConfig.default_auto_field)
Minimal setup:
INSTALLED_APPS += [
"django_mongodb_backend",
"feedwell.feeds",
]
from django.urls import include, path
urlpatterns = [
path("", include("feedwell.feeds.urls")),
]
Then run:
python manage.py migrate
The feeds templates need a login/logout link, but they don't assume any
particular auth url scheme (Django's built-in django.contrib.auth.urls,
django-allauth, or something custom). Add the auth_urls context processor
to your TEMPLATES OPTIONS["context_processors"] so those links resolve
correctly using your project's LOGIN_URL/LOGOUT_URL settings:
TEMPLATES[0]["OPTIONS"]["context_processors"] += [
"feedwell.feeds.context_processors.auth_urls",
]
Optional platform settings for enabling those connect flows in the consuming project:
X_CLIENT_ID = "..."
X_CLIENT_SECRET = "..."
FACEBOOK_CLIENT_ID = "..."
FACEBOOK_CLIENT_SECRET = "..."
If those settings are omitted, X and Facebook simply remain unavailable while Mastodon/Bluesky and the rest of the app continue to work.
Connecting X
Connecting X requires your own X API app (free developer signup at
https://developer.x.com/). Create an app with OAuth 2.0 enabled, set its
callback URL to http://127.0.0.1:8000/connections/x/callback/ (adjust
host/port to match how you run feedwell), then save the credentials with
either of these (a running feedwell reads both, env vars take priority):
feedwell config-set x.client_id "your-client-id"
feedwell config-set x.client_secret "your-client-secret"
export FEEDWELL_X_CLIENT_ID="your-client-id"
export FEEDWELL_X_CLIENT_SECRET="your-client-secret"
feedwell config-set writes to a feedwell.toml file in the current
directory (created automatically the first time you run feedwell, with
commented-out placeholders) so credentials persist across runs without
exporting env vars every session. This file isn't tracked by git.
Note: X now requires your developer Project to be enrolled in its pay-per-use API plan (a payment method on file) before any API v2 call works — including looking up your own profile right after connecting, not just reading timelines. Without that, you'll see a "client-not-enrolled" warning after the OAuth login step succeeds. This is an X-side billing requirement, nothing to fix in feedwell — the connection is still saved (shown as "(pending profile)" until resolved), and clicking Refresh after you enable billing automatically fills in your real profile and starts syncing your timeline, no need to reconnect.
Connecting Facebook
Facebook Login works the same way (create an app at
https://developers.facebook.com/, set its OAuth redirect URI to
http://127.0.0.1:8000/connections/facebook/callback/, then
feedwell config-set facebook.client_id/facebook.client_secret or the
FEEDWELL_FACEBOOK_CLIENT_ID/FEEDWELL_FACEBOOK_CLIENT_SECRET env vars).
Important: this only proves who you are. Meta removed the ability for third-party apps to read a personal News Feed back in 2018 and it has never come back — there's no scope any app can request that returns feed posts for a personal profile, paid or not. Connecting Facebook saves your name/photo and nothing else ever syncs; feedwell tells you this right after you connect.
Status
Early: Account/Post models, Django admin, and a unified-feed view.
Mastodon is fully wired up (OAuth2, home timeline sync). X's connect flow
is wired up too, but reading its timeline requires a paid X API tier.
Facebook Login is wired up as an identity-only connection (no posts ever
sync — see above). Bluesky and RSS aren't connected yet.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file feedwell-0.2.1a1.tar.gz.
File metadata
- Download URL: feedwell-0.2.1a1.tar.gz
- Upload date:
- Size: 62.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5222b936e65fc9d405b6f858f9cbe4785f63bb8dffd0c07f092268bdb8b1e5ff
|
|
| MD5 |
fdd0a4d286b90b3afc7587ae9ac530f1
|
|
| BLAKE2b-256 |
e2945dae6421d1f6a581bb11ccb7a5f088a47e7ec805a0c59ec9407af67c4726
|
Provenance
The following attestation bundles were made for feedwell-0.2.1a1.tar.gz:
Publisher:
workflow.yml on aclark4life/feedwell
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
feedwell-0.2.1a1.tar.gz -
Subject digest:
5222b936e65fc9d405b6f858f9cbe4785f63bb8dffd0c07f092268bdb8b1e5ff - Sigstore transparency entry: 2665203380
- Sigstore integration time:
-
Permalink:
aclark4life/feedwell@395c069bed55e4d05fd34ab88f37e4f1a9b5df77 -
Branch / Tag:
refs/tags/v0.2.1a1 - Owner: https://github.com/aclark4life
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@395c069bed55e4d05fd34ab88f37e4f1a9b5df77 -
Trigger Event:
push
-
Statement type:
File details
Details for the file feedwell-0.2.1a1-py3-none-any.whl.
File metadata
- Download URL: feedwell-0.2.1a1-py3-none-any.whl
- Upload date:
- Size: 80.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
82ae22e0886e04d530f388e7670952721bebabe8d00b209c9c1cda9c6699e54e
|
|
| MD5 |
895967d255536b9ed8a833083bb0bb6a
|
|
| BLAKE2b-256 |
2a238e5f9eee1840d10872aad82cd62ffba59d6dac570d3e28a297860f13aafb
|
Provenance
The following attestation bundles were made for feedwell-0.2.1a1-py3-none-any.whl:
Publisher:
workflow.yml on aclark4life/feedwell
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
feedwell-0.2.1a1-py3-none-any.whl -
Subject digest:
82ae22e0886e04d530f388e7670952721bebabe8d00b209c9c1cda9c6699e54e - Sigstore transparency entry: 2665203407
- Sigstore integration time:
-
Permalink:
aclark4life/feedwell@395c069bed55e4d05fd34ab88f37e4f1a9b5df77 -
Branch / Tag:
refs/tags/v0.2.1a1 - Owner: https://github.com/aclark4life
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@395c069bed55e4d05fd34ab88f37e4f1a9b5df77 -
Trigger Event:
push
-
Statement type: