forem

Stars and mentions

Last 30 days, Oct 4 – Nov 2

GitHub stars39
mentions11
01234Oct 4Oct 18Nov 2
UTC days · repositories forem owns1 repositories

Package downloads

Cumulative recorded downloads · since 2025-10-29

npm10.5K
02.6K5.2K7.9K10.5KOct 4Oct 18Nov 2
Oct 27npm: 1/1 packages observed

Across 1 known packages in repositories forem owns. Cumulative totals include recorded downloads before the selected range. Missing observations leave gaps; totals may be incomplete.

Top repositories

forem’s repositories ranked by pull request authors, as on trending.

Loading

Contributes to

Repositories outside forem’s account where forem opened or reviewed pull requests in the past 365 days.

Who noticed forem

Everyone who starred or forked forem’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

11posts
Nov 30 posts
  1. Something I wanted to see on DEV.to organizations is now a reality. 🚀 !Image description I submitted a PR to Forem to add article pinning for organizations, and it has now been merged! Organizations can now pin up to 5 posts, keeping their most important articles visible above the regular feed. This makes it easier to highlight announcements, useful resources, and content they want visitors to see first. How to pin a post as an organization admin: 1. Go to your dashboard. 2. Find post you want to pin 3. Click Manage. 4. Click the Pin to Organization button. That’s it! Your post will be pinned to your organization’s page. A big thank you to Ben Halpern @ben for the review and guidance, and to everyone involved in getting this merged. It feels great to contribute to a platform I actively use and see an idea turn into a real feature. PR: forem#24058

    50 reactions
  2. Reddit · · r/BestGitHubRepos · u/company_url_finder · forem/forem

    Forem: open source software for building communities, the platform that powers dev.to (23k stars) What it does All text below is quoted directly from the project README. >For empowering community What is Forem?: - Forem is open source software for building communities. - Communities for your peers, customers, fanbases, families, friends, and any other time and space where people need to come together to be part of a collective. - dev.to (or just DEV) is hosted by Forem. - It is a community of software developers who write articles, take part in discussions, and build their professional profiles. - Forem is equipped with Kamal 2 to allow you to easily deploy the application to any cloud provider or bare metal server. - We run on a Rails backend, and we are currently transitioning to a Preact-first frontend. >bundle exec kamal setup Repository forem/forem Repository stats |Metric|Value| |:-|:-| |Stars|22,812| |Forks|4.2k| |Last release|None| |Languages|Ruby 62.1%, JavaScript 16.4%, HTML 11.5%| |Contributors|756| |AI contributor accounts (Claude / Codex / Cursor / Copilot)|@claude (58 commits), @Copilot (70 commits)| |AI co-authored commits|Claude: 60, Copilot: 70| Main contributor |Field|Value| |:-|:-| |Name|Ben Halpern| |GitHub|@benhalpern| |Commits to this repo|3,203 (top contributor)| |Bio|Founder of dev.to| |Company / Location|Forem / New York| |Followers|2.1k| ────────────────────────────── 📌 How many great GitHub repos have you discovered and completely forgotten about? Don't let another useful tool disappear into your Reddit feed. Get the community's best repos, organized by category, plus key takeaways from real developer discussions, delivered to your inbox twice a week. 📬 Never lose track of great repos again. Subscribe free.

    5 points
  3. I Don’t Write Ruby. A Fix I Sent Is Now in Forem. On Oct 22, I read the word "Merged" twice. It was my first contribution to Forem (the platform that hosts dev.to). I don't write Ruby. A coding assistant wrote the code, and it still took 12 weeks. To explain why that word mattered, I have to start in 2019. I kinda discovered dev.to in around April 2019 and at the time I didn't really get into it. It was just one of the many resources I'd search when I wanted to find solutions to bugs or to create features. One time or two it'd show up in my Google search and then I'd click off it. In April 2021 I finally signed up for an account on dev.to. I heard being social is an important aspect to make in this industry. I knew at the time blogging was the easiest for me. I'd never really built a network in the industry, I'd just started following people on LinkedIn and Twitter and my projects were all unknown. I wasn't really the kind of person who'd self-promote and ask for a job. It just wasn't right for me. I'm also an introvert. I wasn't really comfortable meeting new people and I was also very conscious of what they think of me. The Nigerian dev communities didn't help either. They were just hostile to newbies like me. I didn't even have a mentor or friend to learn with. I only ever used the platform to read articles, and I never took the time to write any posts or comments. I didn't even remember my account existed. In November 2025, I created another account to boost my online visibility. I'd noticed that searching my name in Google only resulted in my LinkedIn and Facebook profiles. So here I am, with 62,275 followers and 109 posts. dev.to is the second most used app on my phone (after X), and I refresh it frequently. dev.to is how I met developers outside Nigeria. I had been wanting to dig into Forem for months, but because Forem is built on Rails, and I don't write Ruby, I held off. However, when DEV announced the Summer Bug Smash, and Jess Lee's post came out, that was the final push I needed. The bug fix was small. It took 12 weeks to merge, most of it waiting. Here is how it went. Looking at the code was not the easiest thing to do. I could not tell which issues I could or couldn't fix, so I used an AI coding assistant to help me figure it out. Back in July, the repo had 34 open issues. Some of them were not actually bugs. One was a question the maintainers had already answered. One was an account problem that went to support. And none of the issues were labeled "good first issue". So I chose #23687, which was a small bug: the Posts count on the dashboard was different than the Posts tab. Since the issue description was short, I could follow it. The coding assistant identified the issue and told me how to fix it: the badge was including the count of statuses and archived posts, while the tab was not. The coding assistant wrote the code fix and the tests, and explained what was going on. I recognized it as a typical JavaScript issue: the count didn't match the list after filtering. Here is the fix that was merged. First, the sidebar action sets the count: def sidebar @user = current_user @organizations = @user.admin_organizations @action = params[:state] + @posts_count = posts_count_for(@user) end Then a helper counts the same posts the tab lists: # The "Posts" nav item always links to the default (non-archived, full posts # only) view of the user's own dashboard, so its indicator should reflect # that same scope rather than the user's raw articles_count, which also # includes statuses and archived posts that never show up in that list. def posts_count_for(user) user.articles.from_subforem.full_posts.where(archived: false).count end And the badge reads that number, not articles_count: - <span class="c-indicator"><%= @user.articles_count %></span> + <span class="c-indicator"><%= @posts_count %></span> The mobile menu got the same one-line change. The rest of the PR is the test. Since I did not have Ruby installed on my machine, I couldn't run the tests. I created a PR and let the Forem CI run the tests. I was a bit weirded out that I submitted a PR to code I couldn't read line by line. The CI failed the first time, but the issue was in the test, not the code. The GitHub status also showed "Merging is blocked", and I assumed a maintainer would have to merge it. That was correct. I then signed the CLA, and waited. After a while, I forgot about it, until I got a notification. Then a reviewer approved the PR on Oct 20 and noticed I had added a line I should not have. So I asked the maintainers if they wanted me to remove it, and two days later Mikey (a maintainer) removed it and merged. First, I felt relieved, then proud. That evening, DEV sent me the DEV Contributor badge. It was sent to my old account. I remembered about my old account because of the badge email. Small fixes are still fixes, and now, someone using the dashboard will see the correct post count. I entered the fix in the Summer Bug Smash on Aug 3 while it was still awaiting review. And about 11 weeks later, it got merged. I did not win the Bug Smash, but this counts as a win to me. I learned most of what I know about software development from reading open source projects: the code, documentation, and GitHub issues. This is my first contribution to Forem, and nobody asked me where I was from or what my job title was. They just reviewed my change. That is part of why I love open source. Forem was special, because it was an open source project powering a site I used on a daily basis. The AI coding assistant transformed my side of things. It helped me submit a fix that got merged by a maintainer. And AI changed the other side of things as well. The Forem README welcomes AI-assisted pull requests, and will reject "slop". The repo has an AGENTS.md that outlines how coding assistants should work. The review on my PR says it was written by an AI agent, and the line I should not have added passed the CI. It only got caught by the reviewer. Both sides now have AI, but it is ultimately up to a human to make a decision. That's where the trust comes in. People still question the utility of AI. After the line that slipped past CI, I understand why. I still could not have sent this fix without it. AI might take the ability to write code out of the equation entirely. For example, I know when building an API, I need to spin up a server, create a router, set up route paths to point to handlers, serialize and deserialize the body. When learning a new language, I am trying to figure out how to accomplish these tasks, rather than trying to understand what needs to be accomplished. Removing this limitation also means I can develop with the language more appropriate for the system. AI could change the mindset about hiring, from devs who understand their language to devs who understand systems. If you want to contribute to Forem: - Don't wait for a "good first issue". There were none available in July. - Any issue labeled "bug" and "always open for contribution" is up for grabs. - Verify the issue is a real bug. Some were not. - Check if the issue has an assignee. Some were already taken. - Sign the CLA. That's one comment on your PR. - Add a test. The README says all PRs should include tests. - If you're unable to run the tests locally, state it in your PR, and let CI run the tests. I did, and the failing tests in my first run turned out to be a good thing. - Be patient. My PR took 12 weeks. Special thanks to Jess for posting about the Bug Smash, and for encouraging me to finally dig into the repo; Ben for creating DEV and Forem; Mikey for reviewing my PR, pushing the cleanup, and merging it; and everyone who answered my comments. {% github forem#23690 %}

    23 reactions · 11 comments
  4. DEV · · @dj29 · forem/forem

    I'm Not on the DEV Team. I Still Debugged Their Missing Badges From Public Code. (And My First Test Was Wrong.) I’m not on the DEV team. I don’t have an admin panel, production database access, or internal Slack. Everything I know about how DEV works comes from reading the public forem/forem repository. 🕵️‍♂️ Today, that was enough to diagnose why nobody on DEV was receiving multi-commit contributor badges, ship the service fix upstream, and get a "Thank you for this" and merge from @benhalpern Sir himself. 🚀 !4x DEV Contributor Club badge The 4x DEV Contributor Club badge: "Awarded for 4+ merged commits to Forem — Thank you so much for your contributions!" It also taught me a humbling lesson about tests that pass for the wrong reason. 🧪 --- 1. The Itch: 4 Merged PRs, 1 Badge 🤔 Over the past few days, I went on a contribution sprint in forem/forem and merged four pull requests: - #24003 — Docs: fix broken Kamal TOC anchor and index missing guides - #24056 — A11y: remove duplicate aria-describedby attributes in admin forms - #24094 — A11y: remove dangling aria-describedby references in creator settings - #24095 — Views/Liquids: quote src and add missing alt in user_subscription tag My 1x (dev-contributor) badge showed up right away after PR #1. ✅ When PR #4 merged, I knew from config/schedule.yml that BadgeAchievements::BadgeAwardWorker runs every hour at :20 past the hour (cron: "20 * * * *"). I checked GitHub’s Contributors API (/repos/forem/forem/contributors) and confirmed my account was sitting on page 2 with contributions: 4. Because Forem sets Octokit.auto_paginate = true, the worker was definitely reaching page 2. One hourly cron passed. Then two. Then three. Still no 4x-commit-club badge. 💀 !Mr. Bean waiting and checking his watch Me at :20 past the hour, every hour, refreshing my profile like it owes me money. Instead of refreshing my profile for another 24 hours, I cracked open app/services/badges/award_contributor_from_github.rb. 🔍 --- 2. Reading the Code Like a Detective 🕵️‍♂️ Here is how Badges::AwardContributorFromGithub looked on main: BADGE_SLUGS = { "dev-contributor": 1, "4x-commit-club": 4, "8x-commit-club": 8, "16x-commit-club": 16, "32x-commit-club": 32 }.freeze When I compared award_single_commit_contributors (which awarded my 1x badge) against award_multi_commit_contributors (which handles 4x, 8x, 16x, and 32x), three bugs jumped right off the screen: 🐛 Problem 1: Silent Slug Drops Each key in BADGE_SLUGS is resolved via Badge.id_for_slug(slug). If a slug in the production badges table doesn't match the hardcoded constant, id_for_slug returns nil. The service called .compact on the resulting hash and moved on. No error. No log line. Just a badge tier that quietly vanishes into the void. 👻 Because Forem only exposes resources :badges, only: [:index] without public /badges/:slug show routes, you can't query individual badge slugs directly. However, inspecting the public dev.to/badges catalog gave me a massive clue: > Badge #423 on /badges: > - Title: 4x DEV Contributor Club > - Description: 4x-commit-club Wait—why was 4x-commit-club sitting in the description field while the title was 4x DEV Contributor Club? Because Badge#generate_slug parameterizes the title when no explicit slug is set (4x-dev-contributor-club), the stored slug column in production didn't match the hardcoded "4x-commit-club" constant at all! 💡 !Charlie Day conspiracy board Connecting Badge#generate_slug to DOM element IDs on /badges at 9 AM with zero database access. 💌 Problem 2: Missing Context Messages Single-commit badges were awarded with: BadgeAchievement .where(user_id: i.user_id, badge_id: dev_contributor_badge_id) .first_or_create(rewarding_context_message_markdown: msg) Multi-commit badges, however, were awarded with a bare .create: BadgeAchievement.create(user_id: user_id, badge_id: slug_id) Even when a multi-commit badge was created, it omitted rewarding_context_message_markdown: msg ("Thank you so much for your contributions!"). Four times the commits, zero times the thank-you note. 😭 🔁 Problem 3: Missing Idempotency Guard create_badges_for_user called BadgeAchievement.create(...) on every hourly run instead of .where(...).first_or_create(...). Every hour, it re-attempted already-earned badges for every contributor on the list, relying on ActiveRecord's uniqueness validation to fail silently. Worse, if a badge ever had allow_multiple_awards: true, bare .create would insert a duplicate achievement every hour—firing after_create_commit :notify_recipient and send_email_notification (flooding your inbox from yo@dev.to) each time. 📬💥 --- 3. Filing the Issue & Shipping PR #24113 🛠️ I opened Issue #24114 laying out the slug mismatch on badge IDs 423–426, and paired it with PR #24113 to fix the service itself: 1. ✅ Attached rewarding_context_message_markdown: msg to multi-commit badge awards. 2. 🔒 Replaced bare BadgeAchievement.create with .where(...).first_or_create(...). 3. 📊 Deferred slug lookup behind the GitHub auth provider check and added logging whenever configured slugs are missing from the database. --- 4. The Plot Twist in Code Review 🎬 The initial deep-dive review on @benhalpern Sir’s account was posted by Forem's automated review agent (OpenHands), and it did something awesome—it ran a read-only lookup against the badges table and confirmed my exact diagnosis from Issue #24114: > "I ran a read-only lookup on the badges table for the five BADGE_SLUGS keys. Only one of the five slugs resolves. The four Nx-commit-club slugs have no matching row, so create_badges_for_user skips them and nobody can earn them today. The issue reporter's guess is correct." Bingo. 🎯 Even better, the review caught two subtle flaws in my PR that taught me more than the bug itself: 📢 Lesson A: My Rails.logger.warn Was Log Spam I originally logged a Rails.logger.warn inside the loop for each missing slug. Why was that bad? 1. Until the production slugs were aligned, DEV would log 4 warn lines every hour. 2. Forem powers many independent communities. Most self-hosted Forems enable GitHub auth without seeding DEV-specific contributor badges. Five warn lines an hour for expected configuration turns warn into permanent background noise. The Fix (5e36999): Collect all missing slugs and emit a single Rails.logger.info line per run. 🧹 🤡 Lesson B: My Regression Test Passed on main (For the Wrong Reason!) To test idempotency, I wrote a spec that ran described_class.call twice and asserted that the user still had only 1 badge achievement for 4x-commit-club. It passed! Green dots everywhere. 🟢 Except the review pointed out something brutal: that test also passed on origin/main without my fix. !Surprised Pikachu When your shiny new regression test passes on main without your bugfix. Why? The badge factory defaults to allow_multiple_awards: false. On main, the second BadgeAchievement.create hit validates :badge_id, uniqueness: { scope: :user_id, if: :single_award_badge? }, failed validation silently, and left the count at 1. My test wasn't testing first_or_create at all—it was testing ActiveRecord's uniqueness validator! 🤦‍♂️ The Fix (5e36999): I updated the spec to create the badge with allow_multiple_awards: true (where bare .create genuinely inserts duplicates on main) and asserted expect { described_class.call }.not_to change(BadgeAchievement, :count) on the second run. After I pushed 5e36999 and all 34 checks went green, @benhalpern Sir stepped in personally, dropped a comment: !Ben Halpern approving PR #24113 with "Thank you for this" That "Thank you for this" from @benhalpern Sir genuinely made my entire day! 🙌 And right after that, he merged #24113 into forem:main as d1b962e (my 5th merged PR!). 🎉 !5 merged pull requests in forem/forem Shortly after, the badge email from yo@dev.to hit my inbox and the 4x DEV Contributor Club badge landed on my profile—complete with the "Thank you so much for your contributions!" context message my PR wired up. The code is cleaner, the PR is merged, and the green 4x circuit board is finally home. 💚 --- 💡 3 Takeaways I’d Tell Past Me 1. 🔴 A regression test isn't real until you watch it fail on main. Before you celebrate a green spec, git stash your change and run the spec against main. If it still passes, you haven't written a regression test—you've written a test that agrees with you. 2. 🪵 Log levels are an operator contract. warn means someone should act. If a platform supports optional data seeds, missing optional rows are info, not warn. 3. 🔓 You don't need production access to debug production. You just need the public source code, a falsifiable hypothesis, and the curiosity to follow the trail. Your turn: What’s the sneakiest time one of your tests passed for the completely wrong reason? Drop it in the comments 👇 ---

    40 reactions · 23 comments
  5. 今週のRuby Trendingから、コミュニティ運営を支える基盤を選んだ。 Foremはopen-source community softwareで、dev.xn--to-g73a1a4dn3g7itg9126a.xn--discussionmember-102oka4469lo52k profileを軸に、開発者以外のcommunityにも使える設計です。 forem/forem

    2 likes · 79 views
  6. DEV · · @ben · forem/forem

    Design for Churn The biggest design shift of the AI era isn’t about who writes the code. It’s about how long the code is expected to live. Churn has always been a dirty word in software. Microsoft researchers showed years ago that relative code churn predicts defect density. Adam Tornhill wrote a whole book called Your Code as a Crime Scene, where frequently changed, complex files are the first suspects. GitClear’s research projected that AI assistants would double the share of code rewritten within two weeks of being written, and framed that as downward pressure on quality. The instinct runs deep: code that keeps changing is code that was wrong. But that instinct comes from a world where writing code was expensive. Durability was how you got your money’s worth. When a feature costs an afternoon instead of a sprint, the math flips. Rewriting something is often cheaper than carefully preserving it, and that’s only going to become more true. Codebases are gardens now We’ve always described software in building terms: architecture, foundations, scaffolding, load-bearing walls. Buildings are supposed to stand still. I think codebases are becoming more like gardens. Specifically, gardens full of annuals. A gardener replants annuals every season, and nobody calls a tomato plant technical debt because it dies in October. The gardener’s real investment goes into what doesn’t turn over: the soil, the beds, the irrigation, the oak tree in the corner. Good structure is exactly what makes replanting cheap. Code that churns a lot is essentially disposable, and disposable doesn’t have to mean sloppy. It can still be well made. It just isn’t made to last. Quality for an annual means it does its job, it’s tested at its edges, and it can come out without tearing up everything around it. The problem is that we don’t have a picture of what high-quality churn looks like yet. Our mental model of quality is tangled up with longevity. We brag about code that has run untouched for six years. So churn happens anyway, but implicitly, and it lands wherever is most convenient. Where churn actually lands I looked at the last six months of Forem: 563 commits. The most-churned file is app/models/article.rb, touched in 37 of them. Our spam handler is up there too, at 13. That one I’m happy about. Spam is a seasonal crop. Spammers change tactics constantly, and our code should churn right along with them. article.rb is the oak tree. When the oak gets dug up every week, it means new features are rooting themselves in the core model because that was the easiest place to plant them. That’s the structural compromise. Churn isn’t the problem. Unplanned churn in load-bearing places is. Designing for it A few ideas for making churn explicit instead of accidental: Name the layers. Say out loud what’s an annual and what’s a perennial. Our AGENTS.md already does a crude version of this by telling AI assistants to tread carefully around core auth, feed sorting, and cache pipelines. That should be more than a warning label. It should be the shape of the codebase. Put contracts at the edges of the beds. Interfaces, schemas, API specs, and tests that pin behavior rather than implementation are the perennials. Whatever sits behind them can be rewritten freely, by a person or an agent. Make removal cheap. The test of a good annual is whether you can pull it out without disturbing the bed. If something is meant to churn, it shouldn’t have tendrils in everything. Measure churn by layer. High churn in the fast layer is a sign of health. Churn in the slow layer is the alarm. Churn is a design input Churn is going to happen either way. AI has made it the default rate of change for most of what we build. We can keep treating it as a symptom, or we can treat it as a design input and build the structure that lets us replant with confidence. I will acknowledge that I have always been more of the perspective that churn is more acceptable than conventional wisdom of software design has implied. I’ve never seen the avoidance of churn as being a good thing in my practical experience. I used to see both sides of the argument, now I am staunchly in the camp that churn is positively associated with the quality and rigidity of our codebases and our systems. I’d rather tend the garden than pretend it’s a building.

    52 reactions · 8 comments
  7. DEV · · @ben · forem/forem

    You Should Know About System One Models Production AI usually looks like this: stuff context into a prompt, ask a large language model a yes-or-no question, beg it to answer in JSON, then parse whatever comes back and hope. The punchline is that it actually is incredibly useful to use LLMs for their judgment instead of their writing: is this spam, where does this belong, is this comment actually helpful? LLMs were the best tool for the job, even if they were the wrong tool for the job. The inherent inefficiencies of this idea made scaling an incredibly delicate balancing act of quality, token waste, intelligence and pseudo-determinism. Then Jev came along, and it seems like the missing piece. Judgment as a primitive Jev, from TypeSafe, is a "System One" model. It doesn't generate text. You hand it some state (a comment, a profile, some JSON) and a set of questions, and it returns typed answers with probabilities. There are three shapes: yes/no, pick one from a list, or place it on a scale. That sounds limiting until you notice how much of our LLM usage fits those three boxes. No parsing, no "respond with only one word." Just a decision your code can branch on, plus a probability that tells it when to act and when to escalate. How we use it in Forem In Forem, the open source software that powers DEV, Jev plays two roles. The first is decision maker. It labels new posts for anti-spam moderation, checks whether a post meets a badge's criteria, picks a highlighting language for unlabeled code blocks, and suggests tags for untagged posts. The second, my favorite, is traffic cop. Our spam escalation check is a cheap Jev pass that asks a few questions in parallel: is this spam, is it pushing readers to a Telegram or WhatsApp contact, is it promoting something unrelated to this community? It never flags anything itself. It just decides what deserves a closer look from the full check. Jev is orders of magnitude cheaper than LLMs, and along with lower latency, allows us to inject a layer of intelligence into parts of the system which had to be strictly algorithmic before. Where this is really headed These decisions don't need a frontier data center. They need to be fast, consistent, and close to where things happen. Think about a smart home. Was that a request to turn off the lights, or just a mention of them? Is this motion event worth waking me up for? Those are rigid, reactive, latency-sensitive calls. They should happen locally, without your living room phoning a server farm. That's why I'm rooting for projects like Laya, an open source take on the idea that you can run yourself. It may not be there yet, but someone will make local judgment models work, and when they do, this whole class of AI moves onto the device. Practical problem solving Many production AI use cases wind up as a solution looking for a problem, or simply lack scaled cost-effective usefulness. This tool complements frontier AI intelligence beautifully to maximize the practical roll-out ready usefulness of our systems. I see the release of Jev as not just a usefulness-first AI innovation, but an articulation for how we should be designing tiered intelligence systems to control for costs and provide algorithmic-like control of our outcomes.

    17 reactions · 2 comments
Trending awards, every completed day and week
Gold
21st place finishes
Silver
32nd place finishes
Bronze
13rd place finishes
Awarded repositories
1Owned by forem now

Repositories

Ordered by gold, then silver, then bronze.

  1. foremBest: 1st by stars, 1,303 stars231

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.