{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Open {re}Source",
  "description": "Open source, {re}explained. Articles about open source: tools, contribution, maintenance, community and funding.",
  "home_page_url": "https://openresource.dev/",
  "feed_url": "https://openresource.dev/feed.json",
  "language": "en",
  "items": [
    {
      "id": "https://openresource.dev/articles/cyber-resilience-act-for-maintainers/",
      "url": "https://openresource.dev/articles/cyber-resilience-act-for-maintainers/",
      "title": "The EU Cyber Resilience Act for Open-Source Maintainers, in Plain Words",
      "summary": "Whether the CRA applies to you, what stewards and manufacturers owe, the dates, and what lands on a maintainer's desk, each claim linked to its source.",
      "content_html": "<p class=\"lead\">The Cyber Resilience Act (CRA) is the EU law that makes companies responsible for the security of the software they sell, including the open-source parts. If you maintain a project for free, it almost certainly does not apply to you. If a company ships your project in a product, it applies to them, and they will start asking you questions. Here’s what the law says, in the order you’ll be asked.</p>\n<p>Two texts answer almost everything: <a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng\">the regulation</a> itself, Regulation (EU) 2024/2847, and the <a href=\"https://digital-strategy.ec.europa.eu/en/library/commission-publishes-new-guidance-support-timely-cyber-resilience-act-implementation\">Commission’s guidance</a> of July 27, 2026, whose third chapter is about open source, with 22 worked examples. The guidance is an 84-page PDF; the links below point to the <a href=\"https://cra.orcwg.org/official-guidance/\">copy kept by the Eclipse Foundation’s ORC working group</a>, which has an anchor on every paragraph and example. The guide’s chapter on <a href=\"https://openresource.dev/guide/maintaining/security-for-maintainers/#the-eu-cyber-resilience-act-briefly\">security for maintainers</a> has the three-bullet version.</p>\n<blockquote>\n<p>[!WARNING]\n<strong>This article explains the text; it doesn’t replace someone who can read your situation.</strong> If you sell anything around your project—a paid edition, binaries, support bundled with access—ask a lawyer before December 2027. If your project belongs to a foundation, ask the foundation: it’s the steward, and the CRA is its question first. For everything else, the <a href=\"https://best.openssf.org/CRA-Brief-Guide-for-OSS-Developers.html\">OpenSSF brief guide</a> and the <a href=\"https://cra.orcwg.org/\">ORC working group’s CRA FAQ</a> answer the common cases and link the official texts.</p>\n</blockquote>\n<h2 id=\"three-questions-decide-whether-it-applies-to-you\">Three questions decide whether it applies to you</h2>\n<p>The CRA covers products “made available on the market”, which means supplied “in the course of a commercial activity” (<a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#rct_15\">recital 15</a>). For open source, the guidance turns that into three questions.</p>\n<ol>\n<li><strong>Is the project under your responsibility?</strong> It is if you publish it and control its releases, roadmap and governance: the guidance calls you a maintainer. If you send a pull request that gets merged, you’re a contributor, and the CRA doesn’t apply to you. Commit access alone doesn’t change that (<a href=\"https://cra.orcwg.org/official-guidance/#pnt_49\">para 49</a>, <a href=\"https://cra.orcwg.org/official-guidance/#exm_13\">Example 13</a>, <a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#rct_18\">recital 18</a>).</li>\n<li><strong>Do you monetize it?</strong> Software “not monetised by their manufacturers” is out, in the regulation’s words (<a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#rct_18\">recital 18</a>). If you do, you’re its manufacturer, with the full set of obligations. The next section draws that line.</li>\n<li><strong>If you don’t, who are you?</strong> An individual has no obligations, even when three companies ship the project and donate to it (<a href=\"https://cra.orcwg.org/official-guidance/#exm_27\">Example 27</a>). A legal person, like a foundation or a company, that supports the project on a sustained basis for commercial use is its open-source software steward, with a light set of obligations (<a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#art_3\">Article 3(14)</a>, <a href=\"https://cra.orcwg.org/official-guidance/#sct_3.sct_3\">section 3.3</a>).</li>\n</ol>\n<p>The guidance’s examples, sorted by the role they end in:</p>\n<figure class=\"category-map\" aria-label=\"Who is what under the CRA: no obligations, open-source software steward, or manufacturer. Each box links to the example in the Commission guidance.\" data-astro-cid-ccffcloj><div class=\"category-map__group\" data-astro-cid-ccffcloj><p class=\"category-map__title\" id=\"category-map-0\" data-astro-cid-ccffcloj>No obligations</p><ul class=\"category-map__list\" aria-labelledby=\"category-map-0\" data-astro-cid-ccffcloj><li class=\"category-map__item\" data-astro-cid-ccffcloj><a href=\"https://cra.orcwg.org/official-guidance/#exm_13\" data-astro-cid-ccffcloj>Contributor</a><span class=\"category-map__examples\" data-astro-cid-ccffcloj>A merged pull request, even with commit access</span></li><li class=\"category-map__item\" data-astro-cid-ccffcloj><a href=\"https://cra.orcwg.org/official-guidance/#exm_27\" data-astro-cid-ccffcloj>Individual maintainer</a><span class=\"category-map__examples\" data-astro-cid-ccffcloj>Free, with donations, even from the companies that ship it</span></li><li class=\"category-map__item\" data-astro-cid-ccffcloj><a href=\"https://cra.orcwg.org/official-guidance/#exm_23\" data-astro-cid-ccffcloj>Paid for a feature</a><span class=\"category-map__examples\" data-astro-cid-ccffcloj>A company funds it, the result is free for everyone</span></li><li class=\"category-map__item\" data-astro-cid-ccffcloj><a href=\"https://cra.orcwg.org/official-guidance/#exm_34\" data-astro-cid-ccffcloj>Registry or forge</a><span class=\"category-map__examples\" data-astro-cid-ccffcloj>Hosting the package is not supplying it</span></li></ul></div><div class=\"category-map__group category-map__group--alt\" data-astro-cid-ccffcloj><p class=\"category-map__title\" id=\"category-map-1\" data-astro-cid-ccffcloj>Steward (Article 24)</p><ul class=\"category-map__list\" aria-labelledby=\"category-map-1\" data-astro-cid-ccffcloj><li class=\"category-map__item\" data-astro-cid-ccffcloj><a href=\"https://cra.orcwg.org/official-guidance/#exm_28\" data-astro-cid-ccffcloj>Foundation</a><span class=\"category-map__examples\" data-astro-cid-ccffcloj>Hosts and supports a project companies ship</span></li><li class=\"category-map__item\" data-astro-cid-ccffcloj><a href=\"https://cra.orcwg.org/official-guidance/#exm_29\" data-astro-cid-ccffcloj>Company library</a><span class=\"category-map__examples\" data-astro-cid-ccffcloj>Published for free, also used in its own products</span></li><li class=\"category-map__item\" data-astro-cid-ccffcloj><a href=\"https://cra.orcwg.org/official-guidance/#exm_24\" data-astro-cid-ccffcloj>Not-for-profit with revenue</a><span class=\"category-map__examples\" data-astro-cid-ccffcloj>A browser funded by search deals</span></li></ul></div><div class=\"category-map__group\" data-astro-cid-ccffcloj><p class=\"category-map__title\" id=\"category-map-2\" data-astro-cid-ccffcloj>Manufacturer (Article 13)</p><ul class=\"category-map__list\" aria-labelledby=\"category-map-2\" data-astro-cid-ccffcloj><li class=\"category-map__item\" data-astro-cid-ccffcloj><a href=\"https://cra.orcwg.org/official-guidance/#exm_17\" data-astro-cid-ccffcloj>Paid edition</a><span class=\"category-map__examples\" data-astro-cid-ccffcloj>Support or tuning only in the version you pay for</span></li><li class=\"category-map__item\" data-astro-cid-ccffcloj><a href=\"https://cra.orcwg.org/official-guidance/#exm_21\" data-astro-cid-ccffcloj>Releases for donors</a><span class=\"category-map__examples\" data-astro-cid-ccffcloj>Binaries, updates or fixes only for those who pay</span></li><li class=\"category-map__item\" data-astro-cid-ccffcloj><a href=\"https://cra.orcwg.org/official-guidance/#exm_14\" data-astro-cid-ccffcloj>Free app that sells</a><span class=\"category-map__examples\" data-astro-cid-ccffcloj>A marketplace, a VPN with paid servers, data for ads</span></li><li class=\"category-map__item\" data-astro-cid-ccffcloj><a href=\"https://cra.orcwg.org/official-guidance/#pnt_88\" data-astro-cid-ccffcloj>Whoever ships your code</a><span class=\"category-map__examples\" data-astro-cid-ccffcloj>In a product sold in the EU</span></li></ul></div></figure>\n<p>If you maintain a project as part of your job and your employer publishes it without selling it, your employer is probably its steward (<a href=\"https://cra.orcwg.org/official-guidance/#exm_25\">Examples 25 and 29</a>). The obligations are the company’s, not yours personally: the cybersecurity policy is a question for your manager.</p>\n<h2 id=\"getting-paid-is-fine-charging-for-access-is-not\">Getting paid is fine, charging for access is not</h2>\n<p><strong>What makes you a manufacturer is putting the software, or its fixes, behind a payment.</strong> How the work was funded doesn’t count (<a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#rct_18\">recital 18</a>).</p>\n<table>\n<thead>\n<tr>\n<th>Not monetized: no obligations</th>\n<th>Monetized: manufacturer</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Donations, even above your costs, reasonable living expenses included (<a href=\"https://cra.orcwg.org/official-guidance/#pnt_61\">para 61</a>)</td>\n<td>Releases or security updates only for donors (<a href=\"https://cra.orcwg.org/official-guidance/#exm_21\">Examples 21 and 22</a>)</td>\n</tr>\n<tr>\n<td>A company paying you to build a feature that everyone gets (<a href=\"https://cra.orcwg.org/official-guidance/#exm_23\">Example 23</a>)</td>\n<td>A price for the software or its binaries (<a href=\"https://cra.orcwg.org/official-guidance/#pnt_51\">para 51</a>)</td>\n</tr>\n<tr>\n<td>Consulting, training or support sold next to free downloads (<a href=\"https://cra.orcwg.org/official-guidance/#exm_18\">Example 18</a>)</td>\n<td>A paid edition with support bundled in (<a href=\"https://cra.orcwg.org/official-guidance/#exm_17\">Example 17</a>)</td>\n</tr>\n<tr>\n<td>Sponsorships, grants, bug bounties (<a href=\"https://cra.orcwg.org/official-guidance/#pnt_63\">para 63</a>)</td>\n<td>Use conditioned on personal data for ads or analytics (<a href=\"https://cra.orcwg.org/official-guidance/#exm_16\">Example 16</a>)</td>\n</tr>\n<tr>\n<td>Regular releases (<a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#rct_18\">recital 18</a>)</td>\n<td>A free app through which you sell other services (<a href=\"https://cra.orcwg.org/official-guidance/#exm_14\">Examples 14 and 15</a>)</td>\n</tr>\n</tbody>\n</table>\n<p>Open core splits in two: the paid version is placed on the market, the free community version is not (<a href=\"https://cra.orcwg.org/official-guidance/#pnt_52\">para 52</a>). A company that publishes both is the manufacturer of one and the steward of the other (<a href=\"https://cra.orcwg.org/official-guidance/#pnt_53\">para 53</a>).</p>\n<h2 id=\"reporting-started-in-september-2026-the-rest-comes-in-december-2027\">Reporting started in September 2026, the rest comes in December 2027</h2>\n<ol class=\"timeline\" aria-label=\"The Cyber Resilience Act's dates, 2024 to 2027\" data-astro-cid-3xih677i><li class=\"timeline__entry\" data-astro-cid-3xih677i><span class=\"timeline__year\" data-astro-cid-3xih677i>2024</span><span class=\"timeline__rail\" aria-hidden=\"true\" data-astro-cid-3xih677i></span><span class=\"timeline__body\" data-astro-cid-3xih677i><span class=\"timeline__title\" data-astro-cid-3xih677i>The CRA enters into force</span><span class=\"timeline__detail\" data-astro-cid-3xih677i>Published in the Official Journal on November 20, in force on December 10 (Article 71)</span></span></li><li class=\"timeline__entry\" data-astro-cid-3xih677i><span class=\"timeline__year\" data-astro-cid-3xih677i>2026</span><span class=\"timeline__rail\" aria-hidden=\"true\" data-astro-cid-3xih677i></span><span class=\"timeline__body\" data-astro-cid-3xih677i><span class=\"timeline__title\" data-astro-cid-3xih677i>The Commission publishes its guidance, with a chapter on open source</span><span class=\"timeline__detail\" data-astro-cid-3xih677i>July 27, 2026</span></span></li><li class=\"timeline__entry\" data-astro-cid-3xih677i><span class=\"timeline__year\" data-astro-cid-3xih677i>2026</span><span class=\"timeline__rail\" aria-hidden=\"true\" data-astro-cid-3xih677i></span><span class=\"timeline__body\" data-astro-cid-3xih677i><span class=\"timeline__title\" data-astro-cid-3xih677i>Manufacturers must report actively exploited vulnerabilities and severe incidents</span><span class=\"timeline__detail\" data-astro-cid-3xih677i>From September 11, 2026, through ENISA&#39;s Single Reporting Platform, for products already on the market too (Articles 14 and 69(3))</span></span></li><li class=\"timeline__entry timeline__entry--accent\" data-astro-cid-3xih677i><span class=\"timeline__year\" data-astro-cid-3xih677i>2027</span><span class=\"timeline__rail\" aria-hidden=\"true\" data-astro-cid-3xih677i></span><span class=\"timeline__body\" data-astro-cid-3xih677i><span class=\"timeline__title\" data-astro-cid-3xih677i>Everything else applies: the security requirements, SBOMs, support periods, reporting to upstream projects, and the stewards&#39; obligations</span><span class=\"timeline__detail\" data-astro-cid-3xih677i>December 11, 2027 (Article 71(2))</span></span></li></ol>\n<p>The reporting deadlines are short: an early warning within 24 hours of becoming aware of an actively exploited vulnerability, a notification within 72 hours, and a final report within 14 days of a fix being available (<a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#art_14\">Article 14</a>). Stewards report only from December 11, 2027 (the Commission’s <a href=\"https://digital-strategy.ec.europa.eu/en/policies/cra-reporting\">reporting page</a>), and so does the rule that matters most to you as a maintainer, the duty to report upstream, which is part of <a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#art_13\">Article 13</a>.</p>\n<h2 id=\"stewards-owe-a-policy-not-a-ce-mark\">Stewards owe a policy, not a CE mark</h2>\n<p>A steward’s obligations fit in <a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#art_24\">Article 24</a>: a documented cybersecurity policy that fosters secure development and vulnerability handling, cooperation with market surveillance authorities when they ask, and reporting only as far as the steward is involved. A foundation that only handles branding and donations isn’t required to report anything; one that runs the forge or the signing keys reports incidents on that infrastructure; one that employs the developers reports actively exploited vulnerabilities too (<a href=\"https://cra.orcwg.org/official-guidance/#pnt_79\">paras 79 to 82</a>).</p>\n<p>Stewards can’t put a CE marking on the software (<a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#rct_19\">recital 19</a>), and <strong>they can’t be fined under the CRA</strong> (<a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#art_64\">Article 64(10)</a>). Being a steward is per project: a foundation can be the steward of some of the projects it hosts and nothing for others (<a href=\"https://cra.orcwg.org/official-guidance/#pnt_78\">para 78</a>). If your project is joining one, the guide’s chapter on governance covers <a href=\"https://openresource.dev/guide/maintaining/governance/#join-a-foundation-when-others-depend-on-you\">when a foundation makes sense</a>; ask the foundation how it handles the CRA before you join.</p>\n<h2 id=\"manufacturers-owe-the-work-including-some-of-it-to-you\">Manufacturers owe the work, including some of it to you</h2>\n<p>A manufacturer meets the security requirements of <a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#anx_I\">Annex I</a>, and from December 11, 2027 that includes:</p>\n<ul>\n<li><strong>An SBOM</strong> “covering at the very least the top-level dependencies” (Annex I, Part II, point 1).</li>\n<li><strong>A support period</strong> of at least five years, unless the product is expected to be used for less (<a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#art_13\">Article 13(8)</a>).</li>\n<li><strong>Security updates kept available</strong> for 10 years after they’re issued, or the rest of the support period if that’s longer (Article 13(9)).</li>\n<li><strong>Due diligence on every component</strong> they integrate, open source included (Article 13(5)): checking that it receives security updates and that it has no known vulnerabilities in public databases, among other measures (<a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#rct_34\">recital 34</a>).</li>\n<li><strong>Reporting upstream</strong> (Article 13(6)): a manufacturer that finds a vulnerability in your component must report it to you, unless it can confirm you already know, and if it writes a fix, share it with you.</li>\n</ul>\n<p>Fines for manufacturers go up to €15 million or 2.5% of worldwide annual turnover (Article 64(2)). That number explains the tone of some of the emails you’ll get.</p>\n<p>The guide’s chapter on <a href=\"https://openresource.dev/guide/at-work/vulnerabilities-and-the-cra/\">vulnerabilities in what you ship</a> covers the same obligations from the manufacturer’s desk, before the emails are sent.</p>\n<h2 id=\"what-lands-on-your-desk\">What lands on your desk</h2>\n<p><strong>None of this obliges you to do anything.</strong> A maintainer whose project isn’t placed on the market bears no obligations toward the companies that integrate it (<a href=\"https://cra.orcwg.org/official-guidance/#pnt_87\">para 87</a>). What changes is your inbox.</p>\n<p><strong>Vulnerability reports.</strong> The guidance asks manufacturers to report through your security policy or reporting channel when you have one, to skip reports when they can confirm you already know, and to check public databases and your advisories first (<a href=\"https://cra.orcwg.org/official-guidance/#pnt_223\">para 223</a>). A <code>SECURITY.md</code> with a private channel decides where those reports land and how they’re written. The security chapter has <a href=\"https://openresource.dev/guide/maintaining/security-for-maintainers/#before-the-first-report-one-file-and-four-settings\">a template and the four settings</a> that go with it.</p>\n<p><strong>Patches.</strong> A shared fix should come under a license compatible with yours, and follow your guidelines for sharing fixes if you have some (<a href=\"https://cra.orcwg.org/official-guidance/#pnt_227\">para 227</a>). The manufacturer doesn’t have to get it merged (<a href=\"https://cra.orcwg.org/official-guidance/#pnt_228\">para 228</a>), and you don’t have to merge it.</p>\n<p><strong>Questionnaires and “please sign this”.</strong> The OpenSSF <a href=\"https://policy.openssf.org/CRA/maintainers.html\">CRA guidelines for maintainers</a> list what to expect: security questionnaires, supplier onboarding, compliance declarations. Their advice, as of October 2026, is not to sign anything that takes on CRA compliance, certifies a downstream product or guarantees the absence of vulnerabilities. That’s the OpenSSF reading, not the law’s text, but it matches the regulation: the obligations stay with whoever places the product on the market.</p>\n<p><strong>Due diligence questions you can answer in advance.</strong> Two of the checks the regulation suggests are public: whether you ship security updates, and whether your releases have known vulnerabilities. A supported-versions table in <code>SECURITY.md</code>, <a href=\"https://openresource.dev/guide/maintaining/security-for-maintainers/#one-advisory-gets-you-a-cve-and-alerts-every-user\">published advisories</a> and a <a href=\"https://openresource.dev/guide/creating/repository-files/#a-changelog-is-written-for-the-people-upgrading\">changelog</a> answer both without a questionnaire.</p>\n<p>When a request goes beyond that, the answer can be “no”, or “yes, under a support contract”. <a href=\"https://openresource.dev/guide/maintaining/saying-no/#five-kinds-of-no-with-the-reply-to-save\">Saying No</a> has the replies. A support contract next to free downloads doesn’t make you a manufacturer (<a href=\"https://cra.orcwg.org/official-guidance/#exm_18\">Example 18</a>).</p>\n<h2 id=\"where-the-money-is\">Where the money is</h2>\n<p>As of October 2026:</p>\n<ul>\n<li><strong>Sovereign Tech Resilience</strong>, the German Sovereign Tech Agency’s program, <a href=\"https://www.sovereign.tech/news/resilience-relaunch\">relaunched on September 28, 2026</a> with a CRA compliance service for critical open-source projects: an assessment against the regulation and help closing the gaps, delivered by EY Consulting at no cost to the project. Applications are reviewed on a rolling basis.</li>\n<li><strong>The security funds</strong> the guide already lists, from Alpha-Omega to the GitHub Secure Open Source Fund: see <a href=\"https://openresource.dev/guide/maintaining/security-for-maintainers/#you-dont-have-to-do-it-alone\">You don’t have to do it alone</a>.</li>\n<li><strong>The manufacturers themselves.</strong> They now have a legal reason to care about your release process, and a support contract is a way for them to pay for it.</li>\n</ul>\n<p>The regulation also lets the Commission set up voluntary security attestation programs for open source, which anyone could fund, including the companies that depend on a project (<a href=\"https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#art_25\">Article 25</a>). If one appears, it would answer due diligence once instead of questionnaire by questionnaire.</p>\n<h2 id=\"go-further\">Go further</h2>\n<ul>\n<li><a href=\"https://digital-strategy.ec.europa.eu/en/policies/cra-open-source\">The Commission’s page on the CRA and open source</a>: the official summary of the open-source rules, in a few paragraphs.</li>\n<li><a href=\"https://cra.orcwg.org/official-guidance/#sct_3\">Chapter 3 of the guidance</a>: all 22 open-source examples, and the flowchart that sums them up.</li>\n<li><a href=\"https://policy.openssf.org/CRA/maintainers.html\">The OpenSSF CRA guidelines for maintainers</a>: what to publish, and what not to sign.</li>\n<li><a href=\"https://openresource.dev/guide/maintaining/security-for-maintainers/\">Security for Maintainers</a>: the <code>SECURITY.md</code>, the private reports and the advisories that answer most of the questions above.</li>\n</ul>",
      "date_published": "2026-10-03T00:00:00.000Z",
      "date_modified": "2026-10-07T00:00:00.000Z",
      "tags": [
        "Security",
        "Regulation"
      ]
    },
    {
      "id": "https://openresource.dev/articles/hacktoberfest/",
      "url": "https://openresource.dev/articles/hacktoberfest/",
      "title": "Hacktoberfest: What It Is, How to Take Part, and Lessons From Twelve Years",
      "summary": "What Hacktoberfest is, how to take part in October 2026 now that pull requests no longer count, and what twelve years of it taught open source, good and bad.",
      "content_html": "<p class=\"lead\">Every October since 2014, Hacktoberfest has asked developers to send pull requests to open source projects and get a T-shirt for it. It made hundreds of thousands of first contributions happen, and some years it also left maintainers with waves of low-effort pull requests to sort through. On August 19, 2026, its new organizers dropped the rule that defined it: pull requests no longer count. This is what Hacktoberfest is in 2026, how to take part whether it’s your first Hacktoberfest or your tenth, and what twelve years of it taught open source.</p>\n<h2 id=\"what-hacktoberfest-is\">What Hacktoberfest is</h2>\n<p>Hacktoberfest is a free, month-long event that runs every October. <a href=\"https://www.digitalocean.com/\">DigitalOcean</a> launched it in 2014 with a simple deal: open four pull requests on GitHub during the month, get a T-shirt. 676 people registered that first year and 505 completed it. By 2018, <a href=\"https://www.digitalocean.com/blog/a-review-of-hacktoberfest-year-5\">106,582 had registered</a>; by 2020, <a href=\"https://www.digitalocean.com/blog/hacktoberfest-recap2020\">169,886</a>. Over twelve editions, DigitalOcean counts <a href=\"https://www.digitalocean.com/blog/hacktoberfest-2025-wrapup\">more than 2.4 million accepted pull and merge requests</a> sent to open source projects.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/hacktoberfest-1.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/hacktoberfest-1.png\" alt=\"Hacktoberfest 2026 homepage: a world map of Fests, with 146 in India, powered by MLH and DEV, DigitalOcean presenting.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"450\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"Hacktoberfest 2026 homepage: a world map of Fests, with 146 in India, powered by MLH and DEV, DigitalOcean presenting.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/hacktoberfest-1.png\" alt=\"Hacktoberfest 2026 homepage: a world map of Fests, with 146 in India, powered by MLH and DEV, DigitalOcean presenting.\" width=\"720\" height=\"450\" data-astro-cid-lanmunwp></dialog></div>\n<p>In 2026, <a href=\"https://mlh.io/\">Major League Hacking</a> (MLH) and <a href=\"https://dev.to/\">DEV</a> run the event, with DigitalOcean as presenting partner. The theme is “AI belongs to everyone”, and the month is built around 300+ one-day, in-person events called Fests, an online program of challenges and livestreams about open-source AI, and virtual stickers that turn into a real sticker pack in the mail. Anyone aged 13 or older can take part, and it costs nothing.</p>\n<p>What it is no longer is a pull request counter. To understand why that matters, and to read the labels and contributing guides projects still carry, you need the old rules first.</p>\n<h2 id=\"the-rules-youll-still-find-on-projects\">The rules you’ll still find on projects</h2>\n<p>For eleven editions, the event was a checklist, and projects wrote their contributing guides, labels and issue templates around it. Those are still there, so a newcomer in October 2026 meets both sets of rules at once.</p>\n<ol class=\"timeline\" aria-label=\"Hacktoberfest's rules, 2014 to 2026\" data-astro-cid-3xih677i><li class=\"timeline__entry\" data-astro-cid-3xih677i><span class=\"timeline__year\" data-astro-cid-3xih677i>2014</span><span class=\"timeline__rail\" aria-hidden=\"true\" data-astro-cid-3xih677i></span><span class=\"timeline__body\" data-astro-cid-3xih677i><span class=\"timeline__title\" data-astro-cid-3xih677i>Four pull requests to any public repository, a T-shirt in return</span><span class=\"timeline__detail\" data-astro-cid-3xih677i>676 registered, 505 completed</span></span></li><li class=\"timeline__entry\" data-astro-cid-3xih677i><span class=\"timeline__year\" data-astro-cid-3xih677i>2020</span><span class=\"timeline__rail\" aria-hidden=\"true\" data-astro-cid-3xih677i></span><span class=\"timeline__body\" data-astro-cid-3xih677i><span class=\"timeline__title\" data-astro-cid-3xih677i>Projects opt in with the hacktoberfest topic; pull requests count once merged or labeled hacktoberfest-accepted; spam disqualifies</span><span class=\"timeline__detail\" data-astro-cid-3xih677i>Changed on October 3, three days into the event. 169,886 registered, 9,598 pull requests flagged as spam or invalid</span></span></li><li class=\"timeline__entry\" data-astro-cid-3xih677i><span class=\"timeline__year\" data-astro-cid-3xih677i>2023</span><span class=\"timeline__rail\" aria-hidden=\"true\" data-astro-cid-3xih677i></span><span class=\"timeline__body\" data-astro-cid-3xih677i><span class=\"timeline__title\" data-astro-cid-3xih677i>No more T-shirt: a digital badge, and a tree planted for the first 50,000 accepted first pull requests</span><span class=\"timeline__detail\" data-astro-cid-3xih677i>98,855 registered, 118,469 accepted pull requests</span></span></li><li class=\"timeline__entry\" data-astro-cid-3xih677i><span class=\"timeline__year\" data-astro-cid-3xih677i>2025</span><span class=\"timeline__rail\" aria-hidden=\"true\" data-astro-cid-3xih677i></span><span class=\"timeline__body\" data-astro-cid-3xih677i><span class=\"timeline__title\" data-astro-cid-3xih677i>Six pull requests instead of four; a T-shirt again for the first 10,000 to finish</span><span class=\"timeline__detail\" data-astro-cid-3xih677i>56,768 registered, 87,929 accepted pull requests, 23,592 repositories opted in</span></span></li><li class=\"timeline__entry timeline__entry--accent\" data-astro-cid-3xih677i><span class=\"timeline__year\" data-astro-cid-3xih677i>2026</span><span class=\"timeline__rail\" aria-hidden=\"true\" data-astro-cid-3xih677i></span><span class=\"timeline__body\" data-astro-cid-3xih677i><span class=\"timeline__title\" data-astro-cid-3xih677i>Pull requests no longer count: 300+ Fests, online challenges and stickers, run by MLH and DEV</span><span class=\"timeline__detail\" data-astro-cid-3xih677i>Announced on August 19, 2026</span></span></li></ol>\n<p>Until 2025, you registered on hacktoberfest.com with your GitHub or GitLab account and opened your pull requests between October 1 and October 31. A pull request counted when the repository carried the <span class=\"d-badge d-badge--neutral\">hacktoberfest</span> topic, or when a maintainer put the <span class=\"d-badge d-badge--neutral\">hacktoberfest-accepted</span> label on it, and when it was merged, approved or labeled as accepted. It then sat in a seven-day review window during which a maintainer could still mark it <span class=\"d-badge d-badge--neutral\">spam</span> or <span class=\"d-badge d-badge--neutral\">invalid</span>. Two spam pull requests and you were out. The count went from four to <a href=\"https://www.digitalocean.com/blog/how-to-participate-hacktoberfest-2025\">six in 2025</a>.</p>\n<p>The reward moved too. The T-shirt ran from 2014 to 2022. For the <a href=\"https://www.digitalocean.com/blog/ten-years-hacktoberfest\">tenth edition</a>, DigitalOcean replaced it with a digital badge from Holopin and a tree for the first 50,000 people to get a first pull request accepted: producing over 50,000 T-shirts and shipping them around the world had taken most of the program’s budget, and in many countries the customs fees cost more than the shirt. In 2025 a limited T-shirt came back for the first 10,000 people with six merged pull requests.</p>\n<h2 id=\"what-changed-in-2026-and-why\">What changed in 2026, and why</h2>\n<p>The announcement came from Jess Lee and Ryan Swift on August 19, 2026, on <a href=\"https://blog.mlh.com/hacktoberfest-2026-ai-belongs-to-everyone-3jl8\">MLH’s blog</a>. The format had started to work against the people it depended on. Maintainers, they wrote, “began to burn out under the volume of low-effort, box-checking pull requests”, and AI tools made it trivial to generate one without generating any value.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/hacktoberfest-2.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/hacktoberfest-2.png\" alt=\"The Hacktoberfest FAQ, 'Pull requests and open source' section, with 'Do I still submit pull requests to earn swag?' boxed.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"170\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The Hacktoberfest FAQ, 'Pull requests and open source' section, with 'Do I still submit pull requests to earn swag?' boxed.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/hacktoberfest-2.png\" alt=\"The Hacktoberfest FAQ, 'Pull requests and open source' section, with 'Do I still submit pull requests to earn swag?' boxed.\" width=\"720\" height=\"170\" data-astro-cid-lanmunwp></dialog></div>\n<p>The <a href=\"https://hacktoberfest.com/questions/\">FAQ</a> answers that question in one sentence: pull requests and merge requests no longer count toward rewards, because the organizers are “listening to maintainer feedback and no longer actively incentivizing PRs”. The same answer encourages you to work on open source anyway. Three things replace the counter.</p>\n<p><strong>Fests.</strong> A Fest is a one-day, in-person event hosted by a local organizer: either a Hack Day, a mini-hackathon with workshops, prizes and MLH funding, or a Meetup, with less structure and no prizes. On October 1, 2026, the <a href=\"https://hacktoberfest.com/fests/\">directory</a> listed 382 of them: 284 Hack Days, 54 Meetups, 33 MLH member events and 9 pop-ups, 146 of them in India.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/hacktoberfest-3.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/hacktoberfest-3.png\" alt=\"The Find a Fest page: 382 events in total, 284 Hack Days, 54 Meetups, with a search box and featured events in October.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"450\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The Find a Fest page: 382 events in total, 284 Hack Days, 54 Meetups, with a search box and featured events in October.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/hacktoberfest-3.png\" alt=\"The Find a Fest page: 382 events in total, 284 Hack Days, 54 Meetups, with a search box and featured events in October.\" width=\"720\" height=\"450\" data-astro-cid-lanmunwp></dialog></div>\n<p><strong>An online program.</strong> DEV runs a <a href=\"https://dev.to/challenges/hacktoberfest\">Weekend Challenge</a> from October 2, then four weekly Open-Source AI Challenges starting October 5, 12, 19 and 26, with cash prizes. MLH runs <a href=\"https://events.mlh.com/events/14553-global-hack-week-hacktoberfest\">Global Hack Week</a> from October 9 to 15: daily workshops streamed on Twitch, mini-events on the MLH Discord, and social, technical and design challenges that earn points. The suggested projects are things like writing your first <code>skills.md</code>, building an open source agent, or fine-tuning an open-weight model. The launch livestream is on October 1 at 15:00 UTC.</p>\n<p><strong>Stickers.</strong> Signing in to <a href=\"https://hacktoberfest.com/my/\">My Hacktoberfest</a> with a MyMLH account and adding your address earns the first two virtual stickers. Every activity earns another: a livestream, a challenge submission, a Fest check-in, joining the Discord. At three, a real sticker pack is mailed to you, 8 to 12 weeks after the month ends. At ten you get a holographic one, and at fifteen you enter a raffle for T-shirts and Arduino boards. T-shirts are otherwise handed out at Fests only, and not guaranteed.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/hacktoberfest-5.webp\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/hacktoberfest-5.webp\" alt=\"The Attend online page: 'Earn stickers, and get stickers shipped to your door', with a sheet of hexagonal virtual stickers.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"450\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The Attend online page: 'Earn stickers, and get stickers shipped to your door', with a sheet of hexagonal virtual stickers.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/hacktoberfest-5.webp\" alt=\"The Attend online page: 'Earn stickers, and get stickers shipped to your door', with a sheet of hexagonal virtual stickers.\" width=\"720\" height=\"450\" data-astro-cid-lanmunwp></dialog></div>\n<h2 id=\"how-to-take-part\">How to take part</h2>\n<h3 id=\"if-its-your-first-hacktoberfest\">If it’s your first Hacktoberfest</h3>\n<ol>\n<li><strong>Register.</strong> Go to <a href=\"https://hacktoberfest.com/\">hacktoberfest.com</a>, open My Hacktoberfest and sign in with a MyMLH account. Add your address if you want the sticker pack. Registration stays open until October 31.</li>\n<li><strong>Pick a Fest or go online.</strong> Search the <a href=\"https://hacktoberfest.com/fests/\">directory</a> by city. A Hack Day asks for a laptop and a day; a Meetup asks for an evening. Online, create a DEV account for the challenges, register for Global Hack Week, and join the MLH Discord. Each challenge publishes its prompt when it opens.</li>\n<li><strong>Make a pull request anyway, to a project you use.</strong> The sticker no longer depends on it, which is the best reason to do it: nobody is rewarding a one-line change to a README, so the change you make can be one that matters. <a href=\"https://openresource.dev/guide/contributing/finding-open-source-projects/\">Finding a Project to Contribute To</a> covers where to look, and <a href=\"https://openresource.dev/guide/contributing/contributing-to-open-source/\">Contributing to Open Source</a> the pull request itself, from the fork to the review.</li>\n<li><strong>Read the project’s October rules before you start.</strong> Projects that took part in past editions still carry the <span class=\"d-badge d-badge--neutral\">hacktoberfest</span> topic, which GitHub counts on 147,637 public repositories on October 1, 2026, and their contributing guides still say what counts for them. Some ask you to comment on the issue and wait before writing code. One pull request at a time: open it, answer its review, then open the next.</li>\n</ol>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/hacktoberfest-4.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/hacktoberfest-4.png\" alt=\"GitHub's hacktoberfest topic page, 147,637 repositories boxed, and free-programming-books first with the topic tag boxed.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"450\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"GitHub's hacktoberfest topic page, 147,637 repositories boxed, and free-programming-books first with the topic tag boxed.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/hacktoberfest-4.png\" alt=\"GitHub's hacktoberfest topic page, 147,637 repositories boxed, and free-programming-books first with the topic tag boxed.\" width=\"720\" height=\"450\" data-astro-cid-lanmunwp></dialog></div>\n<h3 id=\"if-youve-done-this-before\">If you’ve done this before</h3>\n<p><strong>Host a Fest.</strong> Anyone can <a href=\"https://hacktoberfest.com/host/\">apply</a> with a description of their community and a format. A Hack Day comes with MLH funding for food and prizes, swag for the participants, help with the program and a listing in the directory; a Meetup gets the swag and the listing. Confirmation is rolling, within a week of a complete application.</p>\n<p><strong>Review and mentor.</strong> A Fest full of first pull requests needs people who can read a diff and explain a review. If you maintain a project, the chapter on <a href=\"https://openresource.dev/guide/maintaining/reviewing-pull-requests/\">reviewing pull requests</a> is the job description.</p>\n<p><strong>Run your own October.</strong> The official counter is gone, but nothing stops a project from running its own. <a href=\"https://kestra.io/hacktoberfest\">Kestra</a> does, with two tracks, a podium per track, and merchandise for every merged pull request. Its rules are the ones that keep such a program healthy: the issue must be linked from the pull request, you ask to be assigned before you start, and only two of your pull requests can be open at a time. <a href=\"https://www.meilisearch.com/blog/hacktoberfest-stories-from-contributor-to-manager\">Meilisearch</a> has tagged eligible issues and offered swag for years, and answers fast; that is how Bruno Casali went from a Ruby integration contributor in 2021 to the team’s lead, with a job offer ten days after his first pull request.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/hacktoberfest-6.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/hacktoberfest-6.png\" alt=\"Kestra's Hacktoberfest 2026 page: 'Put your October pull requests into Kestra', two tracks, submissions October 1 to 31.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"450\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"Kestra's Hacktoberfest 2026 page: 'Put your October pull requests into Kestra', two tracks, submissions October 1 to 31.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/hacktoberfest-6.png\" alt=\"Kestra's Hacktoberfest 2026 page: 'Put your October pull requests into Kestra', two tracks, submissions October 1 to 31.\" width=\"720\" height=\"450\" data-astro-cid-lanmunwp></dialog></div>\n<p><strong>Decide whether your project opts in.</strong> The topic no longer summons a badge, so the October wave should be smaller; it won’t be zero, because tutorials, lists and a decade of habit still point newcomers at it. If you want them, do what Jessica Wilkins did for freeCodeCamp’s quiz site in 2022, when she <a href=\"https://www.freecodecamp.org/news/what-i-learned-as-a-hacktoberfest-repo-maintainer/\">merged 356 pull requests</a> in the month: issue templates with required fields, issues written with the expected code in them, a contributing guide rewritten for beginners, labels for <span class=\"d-badge d-badge--neutral\">hacktoberfest</span>, <span class=\"d-badge d-badge--neutral\">first-timers-only</span> and <span class=\"d-badge d-badge--neutral\">spam</span>, and saved replies so the hundredth answer is as kind as the first. If you don’t want them, remove the topic, say so in the contributing guide, and use the limits: since June 17, 2026, GitHub lets a repository cap how many pull requests a user without write access can have open, and interaction limits can restrict new accounts for a day or a week. <a href=\"https://openresource.dev/guide/maintaining/saying-no/\">Saying No</a> has the replies to save.</p>\n<h2 id=\"the-good\">The good</h2>\n<p>Hacktoberfest is where a lot of people’s first pull request happened, and the numbers are not small. In 2018, 46,088 people completed the challenge. In 2021, <a href=\"https://www.digitalocean.com/blog/hacktoberfest-2021-recap\">294,451 pull requests were accepted</a> by maintainers. In 2019, <a href=\"https://www.digitalocean.com/blog/recapping-hacktoberfest-6\">673 in-person gatherings</a> took place in 393 cities and 73 countries. In DigitalOcean’s <a href=\"https://www.digitalocean.com/blog/hacktoberfest-survey-results\">2023 survey</a> of 1,237 participants, 78% were positive about the event after the T-shirt was gone, and 59% of the maintainers said it had benefited their project.</p>\n<p>It gave projects a reason to do the work that makes any contribution easier: write the issue properly, label it, answer within the day. The freeCodeCamp quiz site went from 694 to 1,171 questions in one October, and from 42 to 109 stars; the templates and the labels outlived the month. Meilisearch found a team lead. A deadline and a shared occasion do move people: in the same survey, the reasons given for not finishing were time and motivation, not spam.</p>\n<p>And for a newcomer, the event solved the question that stops most first contributions: where do I start? A topic, a label, a month and a thousand projects that had agreed to be patient.</p>\n<h2 id=\"the-bad\">The bad</h2>\n<p>The deal rewarded the count, and the count is easy to fake.</p>\n<div class=\"chat chat-start\" data-astro-cid-r7wgiqdd><div class=\"chat-header\" data-astro-cid-r7wgiqdd>Contributor<span class=\"d-visually-hidden\" data-astro-cid-r7wgiqdd>says</span></div><div class=\"chat-bubble\" data-astro-cid-r7wgiqdd><p>Added “awesome” to the README, please merge for Hacktoberfest 🙏</p></div></div>\n<div class=\"chat chat-end\" data-astro-cid-r7wgiqdd><div class=\"chat-header\" data-astro-cid-r7wgiqdd>Maintainer<span class=\"d-visually-hidden\" data-astro-cid-r7wgiqdd>says</span></div><div class=\"chat-bubble\" data-astro-cid-r7wgiqdd><p>Closing. This isn’t a contribution, and the repository didn’t opt in. Labeling it spam.</p></div></div>\n<div class=\"chat chat-start\" data-astro-cid-r7wgiqdd><div class=\"chat-header\" data-astro-cid-r7wgiqdd>Contributor<span class=\"d-visually-hidden\" data-astro-cid-r7wgiqdd>says</span></div><div class=\"chat-bubble\" data-astro-cid-r7wgiqdd><p>Why so rude?? I just need 4 PRs</p></div></div>\n<p>Invalid pull requests went from 1,861 in 2017 to 11,083 in 2018, 2.7% of the total. In 2020 the wave broke. On September 30, Domenic Denicola, who maintains the WHATWG HTML standard, counted <a href=\"https://domenic.me/hacktoberfest/\">11 spam pull requests</a> closed before the event had started, arriving at about four an hour, and called the event “a corporate-sponsored distributed denial of service attack against the open source maintainer community”. Drew DeVault’s <a href=\"https://drewdevault.com/2020/10/01/Spamtoberfest.html\">Spamtoberfest</a> came out on October 1, and the story ran in The Register and InfoQ. On October 3, DigitalOcean made the event opt-in, three days in. Its <a href=\"https://www.digitalocean.com/blog/hacktoberfest-recap2020\">recap</a> counted 621,104 pull requests that month, 9,598 flagged as spam or invalid, and 172,599 sent to repositories that had never opted in.</p>\n<p>The second problem was quieter: repositories built to be contributed to. “Add your name to the list” projects collected hundreds of one-line pull requests and gave their authors four accepted ones in an afternoon. In 2021 DigitalOcean started excluding repositories that encouraged low-effort contributions; in 2023 the organizers still counted <a href=\"https://github.com/MattIPv4/hacktoberfest-data\">39,859 pull requests</a> sent to excluded repositories, 14.91% of everything they tracked. The same pattern runs outside October: in February 2024, a Git tutorial with 1.4 million views used the Express.js repository as its live example, and <a href=\"https://socket.dev/blog/express-js-spam-prs-commoditization-of-open-source\">hundreds of practice pull requests</a> landed on its maintainers, each one a notification to the repository’s 485 watchers.</p>\n<p>The third problem is the one that ended the counter. From 2023, a pull request could be written by a tool in seconds, with a convincing title and a description that read well. The organizers’ own <a href=\"https://hacktoberfest.com/mission/\">mission page</a> says it: AI tools make low-effort pull requests easier than ever to generate, and maintainers face unprecedented volume and noise. The guide’s chapter on <a href=\"https://openresource.dev/guide/ai/contributing-with-ai-tools/\">contributing with AI tools</a> lists the limits projects adopted in response, from Ghostty’s voucher to LLVM’s labels.</p>\n<p>The participation numbers tell the rest. 169,886 registered in 2020, 146,891 in 2022, 98,855 in 2023, and 56,768 in 2025; DigitalOcean published no recap for 2024. Part of that is the opt-in and the T-shirt, which removed the reasons the spammers came for. Part of it is that fewer people are chasing a portfolio line for a junior job that isn’t there, as a <a href=\"https://tvc-16.science/rip-hacktoberfest.html\">December 2025 post</a> argued. Either way, the event that remains is the one its critics asked for in 2020, and it is a smaller one.</p>\n<h2 id=\"so-should-you-take-part\">So, should you take part?</h2>\n<p>Yes, whether it’s your first Hacktoberfest or your tenth, and not for the stickers. What you get out of it depends on where you start.</p>\n<p>If it’s your first time, go to a Fest if there’s one near you: a room where people make their first pull request together is rarer than a T-shirt. Then make one, to a project you use, with the project’s rules read first. The guide’s <a href=\"https://openresource.dev/guide/contributing/\">Contributing</a> module is the long version, and if you’d rather practice before you send anything to a real project, <a href=\"https://github.com/Open-reSource/my-first-contribution\">My First Contribution</a> is a repository made for exactly that.</p>\n<p>If you have taken part before, the event needs you more than the stickers do: host a Fest, mentor at one, or review the pull requests a Fest sends to the projects you know. And if you maintain a project, October is a good month to decide what you want from new contributors, write it down, and set the limits that let you say yes to the rest.</p>",
      "date_published": "2026-10-01T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "Community",
        "Contribution",
        "Events"
      ]
    },
    {
      "id": "https://openresource.dev/articles/running-a-local-ai-inside-obsidian-with-ollama/",
      "url": "https://openresource.dev/articles/running-a-local-ai-inside-obsidian-with-ollama/",
      "title": "Running a Local AI Inside Obsidian with Ollama",
      "summary": "Learn to set up Ollama with Obsidian for a completely local AI writing assistant. Step-by-step guide to private, offline AI that works with your notes without sending data to the cloud.",
      "content_html": "<p class=\"lead\"><strong>What if your notes could think with you, without sending a single word to the cloud?</strong> In this article, we’ll build a fully local AI setup inside Obsidian using Ollama and the open Gemma 4 model. You’ll learn why local AI makes sense for knowledge work, how to install and test Ollama from the command line, how to connect it to Obsidian using community plugins, and how to use it for practical, everyday note-taking workflows, all while keeping full control over your data.</p>\n<hr/>\n<h2 id=\"why-local-ai-in-a-notes-app\">Why Local AI in a Notes App?</h2>\n<p>Before jumping into installation, it’s worth clarifying what is and isn’t open source in this setup, and why it still aligns strongly with open source values.</p>\n<p><strong><a href=\"https://obsidian.md/\">Obsidian</a> is an application that allows users to create and manage notes using plain text Markdown files stored locally on their devices.</strong></p>\n<p><strong>Obsidian is not open source itself, but supports open source community plugins, and is local-first</strong>:</p>\n<ul>\n<li>Notes are plain Markdown files</li>\n<li>Stored on your own filesystem</li>\n<li>No mandatory account or cloud dependency</li>\n<li>Easy to migrate, back up, or process with other tools</li>\n</ul>\n<p>This dramatically reduces vendor lock-in. Even without Obsidian, your knowledge remains usable.</p>\n<p><strong><a href=\"https://ollama.com/\">Ollama</a> is an open source tool that lets you run AI models locally on your machine:</strong></p>\n<ul>\n<li>Runs open models locally</li>\n<li>Exposes a local HTTP API</li>\n<li>Requires no internet once models are installed</li>\n<li>Never sends your data elsewhere</li>\n</ul>\n<p>Together, Obsidian and Ollama create a powerful combination that aligns with open source values: local notes, local AI for privacy, and knowledge work that you actually control.</p>\n<hr/>\n<h2 id=\"what-well-build\">What We’ll Build</h2>\n<p>By the end of this article, you’ll have:</p>\n<ul>\n<li>Ollama installed and verified from the command line</li>\n<li>The Gemma 4 model running locally</li>\n<li>Obsidian configured with community plugins</li>\n<li>A fully local AI assistant embedded in your notes</li>\n</ul>\n<p>Everything described below has been tested using Gemma 4 with Ollama.</p>\n<p>Let’s consider that Obsidian is already installed on your machine. If you haven’t done so yet, you can download it from <a href=\"https://obsidian.md/\">obsidian.md</a>.</p>\n<hr/>\n<h2 id=\"step-1-install-and-test-ollama-command-line-first\">Step 1: Install and Test Ollama (Command Line First)</h2>\n<div class=\"d-steps-wrap\"><ol class=\"d-steps\">\n<li>\n<p>Install Ollama from the official site at <a href=\"https://ollama.com\">https://ollama.com</a>, or on macOS via</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"sh\"><code><span class=\"line\"><span style=\"color:#8FE1E6\">curl</span><span style=\"color:#C78FEF\"> -fsSL</span><span style=\"color:#F083A7\"> https://ollama.com/install.sh</span><span style=\"color:#E6E8EC\"> | </span><span style=\"color:#8FE1E6\">sh</span></span></code></pre>\n</li>\n<li>\n<p>Verify the installation by running in your terminal:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"sh\"><code><span class=\"line\"><span style=\"color:#8FE1E6\">ollama</span><span style=\"color:#C78FEF\"> --version</span></span></code></pre>\n<p>The output should show the installed version of Ollama.</p>\n</li>\n<li>\n<p>Pull and run the Gemma 4 model with:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"sh\"><code><span class=\"line\"><span style=\"color:#8FE1E6\">ollama</span><span style=\"color:#F083A7\"> run</span><span style=\"color:#F083A7\"> gemma4</span></span></code></pre>\n<p>Once the model is downloaded, you’ll get an interactive prompt. Test it with:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"text\"><code><span class=\"line\"><span>Explain what a local-first application is in one paragraph.</span></span></code></pre>\n<p>If you receive a response, everything is working correctly.</p>\n</li>\n<li>\n<p>Exit the chat with the command:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"sh\"><code><span class=\"line\"><span style=\"color:#8FE1E6\">/bye</span></span></code></pre>\n</li>\n<li>\n<p>Ollama also starts a local API server at <a href=\"http://localhost:11434\">http://localhost:11434</a>.</p>\n<p>Opening this URL in your browser will show the “Ollama API is running” message. This endpoint is what Obsidian will use next.</p>\n</li>\n</ol></div>\n<hr/>\n<h2 id=\"step-2-install-the-required-obsidian-community-plugins\">Step 2: Install the Required Obsidian Community Plugins</h2>\n<p>To connect Obsidian to Ollama, you’ll need two open source Obsidian community plugins created by <a href=\"https://github.com/pfrankov\">Pavel Frankov</a>:</p>\n<ul>\n<li>AI Providers</li>\n<li>Local GPT</li>\n</ul>\n<a class=\"entry not-content\" href=\"https://github.com/pfrankov/obsidian-local-gpt\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/584632?v=4&amp;s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3><span class=\"owner\">pfrankov/</span><br/>obsidian-local-gpt</span><span class=\"description\" data-astro-cid-jxjoqtw3>Local Ollama and OpenAI-like GPT's assistance for maximum privacy and offline access</span></span></a>\n<a class=\"entry not-content\" href=\"https://github.com/pfrankov/obsidian-ai-providers\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/584632?v=4&amp;s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3><span class=\"owner\">pfrankov/</span><br/>obsidian-ai-providers</span><span class=\"description\" data-astro-cid-jxjoqtw3>This plugin is a hub for setting AI providers (OpenAI-like, Ollama and more) in one place.</span></span></a>\n<h3 id=\"ai-providers\">AI Providers</h3>\n<p>Let’s start by installing the <strong>AI Providers</strong> plugin.</p>\n<div class=\"d-steps-wrap\"><ol class=\"d-steps\">\n<li>\n<p>In Obsidian, go to “Settings → Community Plugins → Browse” and search for “AI Providers”.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-1.webp\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-1.webp\" alt=\"Obsidian’s community plugin browser: a search for “AI Providers”, the plugin by Pavel Frankov and its Install button.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"320\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"Obsidian’s community plugin browser: a search for “AI Providers”, the plugin by Pavel Frankov and its Install button.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-1.webp\" alt=\"Obsidian’s community plugin browser: a search for “AI Providers”, the plugin by Pavel Frankov and its Install button.\" width=\"720\" height=\"320\" data-astro-cid-lanmunwp></dialog></div>\n</li>\n<li>\n<p>Click “Install”, then “Enable” to enable the plugin.</p>\n</li>\n<li>\n<p>Click “Options” to configure the plugin:</p>\n<ul>\n<li>In the “AI providers” section, click “+” to add a new provider.</li>\n<li>In the “Add new provider” dialog:\n<ul>\n<li>Select “Ollama” as the provider type.</li>\n<li>Click on the refresh icon of the “Model” field to fetch Gemma 4 from your local Ollama installation.</li>\n<li>Click “Save” to add the provider.</li>\n</ul>\n</li>\n</ul>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-2.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-2.png\" alt=\"The “Add new provider” dialog: type Ollama, URL http://localhost:11434, model gemma4:latest.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"420\" height=\"320\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The “Add new provider” dialog: type Ollama, URL http://localhost:11434, model gemma4:latest.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-2.png\" alt=\"The “Add new provider” dialog: type Ollama, URL http://localhost:11434, model gemma4:latest.\" width=\"420\" height=\"320\" data-astro-cid-lanmunwp></dialog></div>\n</li>\n</ol></div>\n<h3 id=\"local-gpt\">Local GPT</h3>\n<p>Then, install the <strong>Local GPT</strong> plugin.</p>\n<div class=\"d-steps-wrap\"><ol class=\"d-steps\">\n<li>\n<p>In Obsidian, go to “Settings → Community Plugins → Browse” and search for “Local GPT”.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-3.webp\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-3.webp\" alt=\"Obsidian’s community plugin browser: a search for “local gpt”, with Local GPT by Pavel Frankov selected.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"320\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"Obsidian’s community plugin browser: a search for “local gpt”, with Local GPT by Pavel Frankov selected.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-3.webp\" alt=\"Obsidian’s community plugin browser: a search for “local gpt”, with Local GPT by Pavel Frankov selected.\" width=\"720\" height=\"320\" data-astro-cid-lanmunwp></dialog></div>\n</li>\n<li>\n<p>Click “Install”, then “Enable” to enable the plugin.</p>\n</li>\n<li>\n<p>Click “Options” to configure the plugin:</p>\n<ul>\n<li>In the “Main AI Provider”, “Embedding AI Provider”, and “Vision AI Provider” sections, select “Ollama ~ gemma4:latest” from the dropdown.</li>\n</ul>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-4.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-4.png\" alt=\"Local GPT options: the main, embedding and vision AI providers all set to “Ollama ~ gemma4:latest”.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"320\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"Local GPT options: the main, embedding and vision AI providers all set to “Ollama ~ gemma4:latest”.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-4.png\" alt=\"Local GPT options: the main, embedding and vision AI providers all set to “Ollama ~ gemma4:latest”.\" width=\"720\" height=\"320\" data-astro-cid-lanmunwp></dialog></div>\n</li>\n</ol></div>\n<hr/>\n<h2 id=\"step-3-attach-hot-keys-for-quick-access\">Step 3: Attach Hot Keys for Quick Access</h2>\n<p>To quickly access Local GPT features, set up hot keys in Obsidian.</p>\n<div class=\"d-steps-wrap\"><ol class=\"d-steps\">\n<li>\n<p>In Obsidian, go to “Settings → Hotkeys”.</p>\n</li>\n<li>\n<p>Filter by “Local”.</p>\n</li>\n<li>\n<p>Assign hot keys to the following commands:</p>\n<ul>\n<li>For “Local GPT: Action Palette”, click on “+” and press your desired key combination (e.g., <kbd>⌘ + J</kbd>).</li>\n<li>For “Local GPT: Show context menu”, click on “+” and press your desired key combination (e.g., <kbd>⌘ + M</kbd>).</li>\n</ul>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-5.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-5.png\" alt=\"Obsidian hotkeys filtered on “local”: Action Palette on ⌘ J, Show context menu on ⌘ M.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"320\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"Obsidian hotkeys filtered on “local”: Action Palette on ⌘ J, Show context menu on ⌘ M.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-5.png\" alt=\"Obsidian hotkeys filtered on “local”: Action Palette on ⌘ J, Show context menu on ⌘ M.\" width=\"720\" height=\"320\" data-astro-cid-lanmunwp></dialog></div>\n</li>\n</ol></div>\n<hr/>\n<h2 id=\"step-4-test-local-gpt-inside-obsidian\">Step 4: Test Local GPT Inside Obsidian</h2>\n<p>Now that everything is set up, it’s time to test Local GPT inside Obsidian.</p>\n<p>Two hot keys are set up: one for the action palette and one for the context menu.</p>\n<h3 id=\"using-the-context-menu\">Using the Context Menu</h3>\n<p>The context menu is a quick way to apply AI actions to selected text.</p>\n<div class=\"d-steps-wrap\"><ol class=\"d-steps\">\n<li>\n<p>Open any note in Obsidian.</p>\n</li>\n<li>\n<p>Select some text you want to process with AI.</p>\n</li>\n<li>\n<p>Press the hot key you assigned for “Local GPT: Show context menu” (e.g., <kbd>⌘ + M</kbd>). It will open a context menu with various AI actions you can perform on the selected text:</p>\n<ul>\n<li>General help</li>\n<li>Continue writing</li>\n<li>Summarize</li>\n<li>Fix spelling and grammar</li>\n<li>Find action items</li>\n<li>New System Prompt</li>\n</ul>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-6.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-6.png\" alt=\"The Local GPT context menu in a note: General help, Continue writing, Summarize, Fix spelling, Find action items.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"320\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The Local GPT context menu in a note: General help, Continue writing, Summarize, Fix spelling, Find action items.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-6.png\" alt=\"The Local GPT context menu in a note: General help, Continue writing, Summarize, Fix spelling, Find action items.\" width=\"720\" height=\"320\" data-astro-cid-lanmunwp></dialog></div>\n<p>Please note that you can create your own custom prompts as well.</p>\n</li>\n</ol></div>\n<p>Let’s say I’ve written this article in Obsidian first and wanted to summarize it. I would select the text and use the context menu to choose “Summarize”.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-7.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-7.png\" alt=\"A note with the whole article selected and the Local GPT context menu open on Summarize.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"420\" height=\"320\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"A note with the whole article selected and the Local GPT context menu open on Summarize.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-7.png\" alt=\"A note with the whole article selected and the Local GPT context menu open on Summarize.\" width=\"420\" height=\"320\" data-astro-cid-lanmunwp></dialog></div>\n<p>Gemma 4 would then generate a concise summary of the selected content directly at the end of my note (this can be configured).</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-8.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-8.png\" alt=\"The summary written at the end of the note: a heading, a short intro, and bullet points on setup, privacy and trade-offs.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"420\" height=\"320\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The summary written at the end of the note: a heading, a short intro, and bullet points on setup, privacy and trade-offs.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-8.png\" alt=\"The summary written at the end of the note: a heading, a short intro, and bullet points on setup, privacy and trade-offs.\" width=\"420\" height=\"320\" data-astro-cid-lanmunwp></dialog></div>\n<h3 id=\"using-the-action-palette\">Using the Action Palette</h3>\n<p>The action palette allows you to type custom prompts and interact with Local GPT more freely.</p>\n<div class=\"d-steps-wrap\"><ol class=\"d-steps\">\n<li>Open any note in Obsidian.</li>\n<li>Press the hot key you assigned for “Local GPT: Action Palette” (e.g., <kbd>⌘ + J</kbd>). It will open the action palette where you can type your prompt.</li>\n</ol></div>\n<p>Let’s say I want to analyze an image to describe its content. I would select the image in my note, open the action palette, and type: “Describe this image!”</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-9.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-9.png\" alt=\"The Local GPT action palette over a GitHub logo in a note, with the prompt “Describe this image!”.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"420\" height=\"320\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The Local GPT action palette over a GitHub logo in a note, with the prompt “Describe this image!”.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-9.png\" alt=\"The Local GPT action palette over a GitHub logo in a note, with the prompt “Describe this image!”.\" width=\"420\" height=\"320\" data-astro-cid-lanmunwp></dialog></div>\n<p>The model would then generate a description of the image directly in my note.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-10.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-10.png\" alt=\"The description written under the GitHub logo: overall, elements (the cat silhouette, the word GitHub) and style.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"420\" height=\"320\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The description written under the GitHub logo: overall, elements (the cat silhouette, the word GitHub) and style.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/running-a-local-ai-inside-obsidian-with-ollama-10.png\" alt=\"The description written under the GitHub logo: overall, elements (the cat silhouette, the word GitHub) and style.\" width=\"420\" height=\"320\" data-astro-cid-lanmunwp></dialog></div>\n<hr/>\n<h2 id=\"everyday-use-cases-that-actually-feel-useful\">Everyday Use Cases That Actually Feel Useful</h2>\n<p><strong>I just scratched the surface of what you can do with this setup, and honestly, it’s pretty useful for specific tasks.</strong> Gemma 4 works well for close-to-the-text stuff: cleaning up messy first drafts, turning rambling meeting notes into actual bullet points, or getting a quick summary when I don’t want to reread a long note.</p>\n<p>Response times are decent for most tasks. Not instant, but fast enough to keep you in the flow.</p>\n<p>Where I use it most is rewriting awkward sentences, expanding bullet points when I need more detail, or brainstorming different ways to phrase something. It’s also surprisingly good at catching unclear writing that I might miss.</p>\n<p><strong>But it definitely has limits.</strong> It can’t access other notes in my vault (just the current one), struggles with complex reasoning, and sometimes gives generic responses if your prompt is too vague. I’m also not sure how well it handles really technical content as I’ve had mixed results there.</p>\n<p>The key thing I’ve learned is that <strong>it works best as an editing partner for stuff you’ve already written, rather than generating ideas from scratch.</strong></p>\n<p>Maybe a more powerful setup could mix local and cloud models, using local for sensitive stuff and cloud for heavy lifting when needed. But for now, this local-first approach feels like a solid step toward more private, controllable AI in my writing workflow.</p>\n<hr/>\n<h2 id=\"trade-offs-and-why-theyre-worth-it\">Trade-Offs (And Why They’re Worth It)</h2>\n<p>Local AI isn’t perfect:</p>\n<ul>\n<li>Slower than cloud-hosted models</li>\n<li>Smaller context windows</li>\n<li>Less immediate “wow” factor than other cloud paid systems</li>\n</ul>\n<p>But in exchange, you get:</p>\n<ul>\n<li>Privacy by default</li>\n<li>Zero marginal cost</li>\n<li>Full control over models and prompts</li>\n<li>No vendor dependency or platform lock-in</li>\n</ul>\n<p>For personal knowledge management and everyday writing, that trade-off is often not just acceptable, but desirable.</p>\n<hr/>\n<p>If you try out this setup, let me know how it goes! Share your experiences, tips, or custom workflows in our social platforms.</p>\n<p>Happy note-taking!</p>",
      "date_published": "2026-02-01T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "AI",
        "Tools",
        "Tutorial"
      ]
    },
    {
      "id": "https://openresource.dev/articles/coding-linkedin-carousels/",
      "url": "https://openresource.dev/articles/coding-linkedin-carousels/",
      "title": "Coding LinkedIn Carousels",
      "summary": "Creating LinkedIn carousels is a great way to share information in a visually appealing format. Learn how to code LinkedIn carousels with this guide.",
      "content_html": "<p class=\"lead\">Coding LinkedIn carousels… yes, not using design tools but using developer tools! It’s now possible!</p>\n<p>A few days ago, we shared <a href=\"https://www.linkedin.com/posts/open-re-source_generate-github-repositories-top-contributors-activity-7245171076966559745-sBAM/\">a new article on LinkedIn</a> and tried to make it more engaging by using a carousel. And creating a carousel on LinkedIn can take a bit of time, especially if you’re not that familiar with design tools such as <a href=\"https://www.canva.com\">Canva</a>, <a href=\"https://www.figma.com\">Figma</a>, or even <a href=\"https://penpot.app/\">Penpot</a>, our open-source design tool friend. Even with the tons of templates available out there, customizing them is a lot of work.</p>\n<p>In the open-source software world, we are mostly developers, we’re not going to lie. So, we thought: <strong>“Why not code the LinkedIn carousel?” And that’s what we did!</strong></p>\n<h2 id=\"how-linkedin-carousels-work\">How LinkedIn carousels work</h2>\n<p>Just for those who are not familiar with LinkedIn carousels, they are a series of images or slides that you can swipe through. They are a great way to share information in a visually appealing format. You can use them to showcase your open-source project, share tips, or even tell a story.</p>\n<p>There’s no real creator tool for LinkedIn carousels, so you have to create them yourself.</p>\n<p><strong>Basically, a LinkedIn carousel is in fact a PDF file.</strong> You can create a PDF file with multiple pages, and each page will be a slide in your carousel. You can then upload this PDF file to LinkedIn, and it will automatically convert it into a carousel.</p>\n<ol>\n<li>On LinkedIn, click on the “+ Create” button.</li>\n<li>Select “Start a post”.</li>\n<li>Click on the “+” icon, and “Add a document”.</li>\n<li>Select your PDF file, choose a document title, and LinkedIn will convert it into a carousel.</li>\n</ol>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/coding-linkedin-carousels-1.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/coding-linkedin-carousels-1.png\" alt=\"LinkedIn’s post editor, with the “Add a document” button in the toolbar.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"400\" height=\"320\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"LinkedIn’s post editor, with the “Add a document” button in the toolbar.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/coding-linkedin-carousels-1.png\" alt=\"LinkedIn’s post editor, with the “Add a document” button in the toolbar.\" width=\"400\" height=\"320\" data-astro-cid-lanmunwp></dialog></div>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/coding-linkedin-carousels-2.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/coding-linkedin-carousels-2.png\" alt=\"LinkedIn’s “Share a document” dialog: a title field and the PDF’s first slide previewed as a carousel.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"400\" height=\"257\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"LinkedIn’s “Share a document” dialog: a title field and the PDF’s first slide previewed as a carousel.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/coding-linkedin-carousels-2.png\" alt=\"LinkedIn’s “Share a document” dialog: a title field and the PDF’s first slide previewed as a carousel.\" width=\"400\" height=\"257\" data-astro-cid-lanmunwp></dialog></div>\n<h2 id=\"the-idea\">The Idea</h2>\n<p><strong>So, if it just a PDF file, why not code it?</strong> We can create a simple HTML file with multiple slides, and then convert it into a PDF file. And that’s what we did!</p>\n<p>We already use this great tool for presentations, it’s called <a href=\"https://sli.dev/\">Slidev</a>.</p>\n<p>Slidev is a presentation tool based on Vue.js. It allows you to create beautiful slides with Markdown and code. And it has a feature to export your slides as a PDF file. It is an open-source project, under the MIT license.</p>\n<a class=\"entry not-content\" href=\"https://github.com/slidevjs/slidev\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/83095831?v=4&amp;s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3><span class=\"owner\">slidevjs/</span><br/>slidev</span><span class=\"description\" data-astro-cid-jxjoqtw3>Presentation Slides for Developers</span></span></a>\n<h2 id=\"how-to-code-linkedin-carousels\">How to Code LinkedIn Carousels</h2>\n<p>It’s really simple in fact.</p>\n<p>The first step is to create a new Slidev project. You can do this by running the following command:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"sh\"><code><span class=\"line\"><span style=\"color:#8FE1E6\">npm</span><span style=\"color:#F083A7\"> init</span><span style=\"color:#F083A7\"> slidev@latest</span></span></code></pre>\n<p>This will create a new Slidev project in the current directory. You can then open the project in your code editor and start customizing the slides.</p>\n<p>Obviously, you’ll notice that the default Slidev theme is not really suitable for LinkedIn carousels as the slides are generally wide, in a 16:9 ratio. So, you’ll need to customize the theme to make it more suitable for LinkedIn carousels.</p>\n<p>In the <code>slides.md</code> you just have to add the following properties in the frontmatter:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"json\"><code><span class=\"line\"><span style=\"color:#E6E8EC\">---</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">aspectRatio: </span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#F083A7\">3/4</span><span style=\"color:#E6E8EC\">&quot;</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">canvasWidth: </span><span style=\"color:#C78FEF\">800</span></span></code></pre>\n<p>Just install <code>playwright-chromium</code> as a dev dependency, and export your slides as a PDF file:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"sh\"><code><span class=\"line\"><span style=\"color:#8FE1E6\">npm</span><span style=\"color:#F083A7\"> install</span><span style=\"color:#C78FEF\"> -D</span><span style=\"color:#F083A7\"> playwright-chromium</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">npm</span><span style=\"color:#F083A7\"> run</span><span style=\"color:#F083A7\"> export</span></span></code></pre>\n<p>And voilà, you got a nice <code>slides-export.pdf</code> that could be used as a LinkedIn carousel!</p>\n<h2 id=\"we-created-a-theme-for-linkedin-carousels\">We Created a Theme for LinkedIn Carousels</h2>\n<p>However, you’ll notice that you still have some design work to do in order to render your carousel more visually appealing.</p>\n<p><strong>So, we created a theme for LinkedIn carousels called <code>slidev-theme-linkedin-carousel</code></strong>, that is an open-source project under the MIT license.</p>\n<a class=\"entry not-content\" href=\"https://github.com/Open-reSource/slidev-theme-linkedin-carousel\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/129324099?v=4&amp;s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3><span class=\"owner\">Open-reSource/</span><br/>slidev-theme-linkedin-carousel</span><span class=\"description\" data-astro-cid-jxjoqtw3>Slidev theme to create LinkedIn carousels</span></span></a>\n<p>Here’s what it looks like: <a href=\"https://slidev-theme-lk-carousel.netlify.app\">https://slidev-theme-lk-carousel.netlify.app</a>.</p>\n<div style=\"display: grid; gap: 10px; grid-template-columns: repeat(4, 1fr);\"><img src=\"https://cdn.jsdelivr.net/npm/slidev-theme-linkedin-carousel@latest/example-export/1.png\" style=\"border: 1px solid lightgray; border-radius: 10px; margin-top: 0\" alt=\"Cover slide: a placeholder title and sub-title, and an arrow inviting to swipe.\" loading=\"lazy\" decoding=\"async\" width=\"200\" height=\"150\"><img src=\"https://cdn.jsdelivr.net/npm/slidev-theme-linkedin-carousel@latest/example-export/2.png\" style=\"border: 1px solid lightgray; border-radius: 10px; margin-top: 0\" alt=\"Text slide: five lines of placeholder content in large type.\" loading=\"lazy\" decoding=\"async\" width=\"200\" height=\"150\"><img src=\"https://cdn.jsdelivr.net/npm/slidev-theme-linkedin-carousel@latest/example-export/3.png\" style=\"border: 1px solid lightgray; border-radius: 10px; margin-top: 0\" alt=\"Image slide: a title, a sub-title and a full-width photo with its credit.\" loading=\"lazy\" decoding=\"async\" width=\"200\" height=\"150\"><img src=\"https://cdn.jsdelivr.net/npm/slidev-theme-linkedin-carousel@latest/example-export/4.png\" style=\"border: 1px solid lightgray; border-radius: 10px; margin-top: 0\" alt=\"A code snippet, then the GitHubProject component showing a repository card.\" loading=\"lazy\" decoding=\"async\" width=\"200\" height=\"150\"><img src=\"https://cdn.jsdelivr.net/npm/slidev-theme-linkedin-carousel@latest/example-export/5.png\" style=\"border: 1px solid lightgray; border-radius: 10px; margin-top: 0\" alt=\"The Code component, a terminal window, and the Browser component, a window with a URL bar.\" loading=\"lazy\" decoding=\"async\" width=\"200\" height=\"150\"><img src=\"https://cdn.jsdelivr.net/npm/slidev-theme-linkedin-carousel@latest/example-export/6.png\" style=\"border: 1px solid lightgray; border-radius: 10px; margin-top: 0\" alt=\"The Phone component: a phone frame around the slide’s content.\" loading=\"lazy\" decoding=\"async\" width=\"200\" height=\"150\"></div>\n<h3 id=\"how-to-use-the-theme\">How to Use the Theme</h3>\n<p>To use the theme, you just have to install it as a dev dependency:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"sh\"><code><span class=\"line\"><span style=\"color:#8FE1E6\">npm</span><span style=\"color:#F083A7\"> i</span><span style=\"color:#C78FEF\"> -D</span><span style=\"color:#F083A7\"> slidev-theme-linkedin-carousel</span></span></code></pre>\n<p>and then add the following frontmatter to your slides:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"md\"><code><span class=\"line\"><span style=\"color:#E6E8EC\">---</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">theme: linkedin-carousel</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF;font-weight:bold\">---</span></span></code></pre>\n<p>For more information on how to use the theme, check out the <a href=\"https://github.com/Open-reSource/slidev-theme-linkedin-carousel\">README</a>.</p>\n<p>The <code>example.md</code> file in the repository is a good starting point to create your own LinkedIn carousels. And from there, you can customize the slides to your liking, and even use custom components to make them more impacting.</p>\n<hr/>\n<p>Don’t hesitate to share your LinkedIn carousels with us, we’d love to see them! See ya <a href=\"https://www.linkedin.com/company/open-re-source/\">on LinkedIn</a>!</p>\n<p>If you liked this theme, use it, please consider <a href=\"https://github.com/Open-reSource/slidev-theme-linkedin-carousel\">giving it a star on GitHub</a>, or even <a href=\"https://github.com/sponsors/Open-reSource/\">sponsoring us</a>. It helps us a lot!</p>",
      "date_published": "2024-09-29T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "LinkedIn",
        "Social Media",
        "Tools"
      ]
    },
    {
      "id": "https://openresource.dev/articles/add-funding-links-to-your-packagejson/",
      "url": "https://openresource.dev/articles/add-funding-links-to-your-packagejson/",
      "title": "Add Funding Links to Your 'package.json'",
      "summary": "Learn how to add funding links to your 'package.json' file to make it easier to support your open-source project.",
      "content_html": "<p class=\"lead\">Fund your open-source project by adding funding links to your <code>package.json</code> file. Who knows, you might get a coffee or two out of it!</p>\n<h2 id=\"funding-open-source-projects\">Funding Open-Source Projects?</h2>\n<p>If you’re not new to the content of Open {re}Source, you know a thing or two about the importance of <a href=\"https://openresource.dev/guide/financing\">financing and funding open-source projects</a>. The time and effort that maintainers put into their projects are invaluable, and it’s essential to support them in any way possible.</p>\n<p>Supporting open-source projects can be as simple as starring a repository, contributing to the codebase, or even providing financial support. The latter can be done through platforms like <a href=\"https://github.com/sponsors\">GitHub Sponsors</a>, <a href=\"https://opencollective.com/\">Open Collective</a>, or even through direct donations.</p>\n<h2 id=\"packages-are-looking-for-funding\">Packages Are Looking for Funding</h2>\n<p>Have you ever noticed the funding information displayed when you run the <code>npm i</code> command in your terminal?</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>% npm install</span></span>\n<span class=\"line\"><span></span></span>\n<span class=\"line\"><span>247 packages are looking for funding</span></span>\n<span class=\"line\"><span>  run `npm fund` for details</span></span></code></pre>\n<h3 id=\"you-can-turn-it-off-by-the-way\">You Can Turn It Off, by the Way</h3>\n<p>If you’re not a fan of the funding information displayed when installing packages, you can turn it off by setting the <code>--no-fund</code> flag when running the <code>npm install</code> command.</p>\n<p>You can also set it as a default behavior by running <code>npm config set fund false</code>.</p>\n<p>Or you can turn it off in your <code>.npmrc</code> file in your home directory (<code>~/.npmrc</code>) manually or in your project’s <code>.npmrc</code> file:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>fund = false</span></span></code></pre>\n<h2 id=\"npm-fund-command\"><code>npm fund</code> Command</h2>\n<p>Have you already launched <code>npm fund</code> in your terminal? If not, go ahead and do it now in one of your projects.</p>\n<p>Here’s what it looks like for this repository:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>openresource.dev@0.0.0</span></span>\n<span class=\"line\"><span>├── https://opencollective.com/fakerjs</span></span>\n<span class=\"line\"><span>│   └── @faker-js/faker@9.0.1</span></span>\n<span class=\"line\"><span>├── https://dotenvx.com</span></span>\n<span class=\"line\"><span>│   └── dotenv@16.4.5</span></span>\n<span class=\"line\"><span>├── https://github.com/sponsors/wooorm</span></span>\n<span class=\"line\"><span>│   └── gemoji@8.1.0, bcp-47@2.1.0, bcp-47-match@2.0.3, direction@2.0.1, longest-streak@3.1.0, bail@2.0.2, trough@2.2.0, collapse-white-space@2.1.0, comma-separated-tokens@2.0.3, ccount@2.0.1, parse-entities@4.0.1, character-entities-legacy@3.0.0, character-reference-invalid@2.0.1, is-alphanumerical@2.0.1, is-alphabetical@2.0.1, is-decimal@2.0.1, is-hexadecimal@2.0.1, stringify-entities@4.0.4, character-entities-html4@2.1.0, property-information@6.5.0, space-separated-tokens@2.0.2, zwitch@2.0.4, html-void-elements@3.0.0, web-namespaces@2.0.1, markdown-table@3.0.3, import-meta-resolve@4.1.0, decode-named-character-reference@1.0.2, character-entities@2.0.2, devlop@1.1.0, trim-lines@3.0.1, parse-latin@7.0.0, array-iterate@2.0.1</span></span>\n<span class=\"line\"><span>├── https://opencollective.com/vitest</span></span>\n<span class=\"line\"><span>│   └── vitest@2.1.1, @vitest/expect@2.1.1, @vitest/mocker@2.1.1, @vitest/pretty-format@2.1.1, @vitest/runner@2.1.1, @vitest/snapshot@2.1.1, @vitest/spy@2.1.1, @vitest/utils@2.1.1, vite-node@2.1.1</span></span>\n<span class=\"line\"><span>├─┬ https://paulmillr.com/funding/</span></span>\n<span class=\"line\"><span>│ │ └── chokidar@3.6.0</span></span>\n<span class=\"line\"><span>│ ├── https://github.com/sponsors/jonschlinkert</span></span>\n<span class=\"line\"><span>│ │   └── picomatch@2.3.1, picomatch@4.0.2</span></span>\n<span class=\"line\"><span>│ └── https://github.com/sponsors/sindresorhus</span></span>\n<span class=\"line\"><span>│     └── binary-extensions@2.3.0, is-plain-obj@4.1.0, markdown-extensions@2.0.0, escape-string-regexp@5.0.0, make-dir@3.1.0, boxen@7.1.1, camelcase@7.0.1, cli-boxes@3.0.0, string-width@5.1.2, type-fest@2.19.0, widest-line@4.0.1, ora@8.1.0, cli-cursor@5.0.0, restore-cursor@5.1.0, onetime@7.0.0, mimic-function@5.0.1, cli-spinners@2.9.2, is-interactive@2.0.0, is-unicode-supported@2.1.0, log-symbols@6.0.0, is-unicode-supported@1.3.0, stdin-discarder@0.2.2, p-limit@2.3.0, p-queue@8.0.1, p-timeout@6.1.2, string-width@7.2.0, get-east-asian-width@1.2.0, is-docker@3.0.0, is-wsl@3.1.0, is-inside-container@1.0.0, find-up-simple@1.0.0, is-absolute-url@4.0.1, get-stream@5.2.0, is-stream@2.0.1, onetime@5.1.2, pretty-ms@7.0.1, time-span@4.0.0</span></span>\n<span class=\"line\"><span>├── https://github.com/prettier/prettier?sponsor=1</span></span>\n<span class=\"line\"><span>│   └── prettier@2.8.7</span></span>\n<span class=\"line\"><span>├── https://github.com/sponsors/epoberezkin</span></span>\n<span class=\"line\"><span>│   └── ajv@6.12.6</span></span>\n<span class=\"line\"><span>├── https://github.com/sponsors/feross</span></span>\n<span class=\"line\"><span>│   └── run-parallel@1.2.0, queue-microtask@1.2.3, safe-buffer@5.2.1</span></span>\n<span class=\"line\"><span>├─┬ https://github.com/chalk/wrap-ansi?sponsor=1</span></span>\n<span class=\"line\"><span>│ │ └── wrap-ansi@7.0.0, wrap-ansi@8.1.0</span></span>\n<span class=\"line\"><span>│ └── https://github.com/chalk/ansi-styles?sponsor=1</span></span>\n<span class=\"line\"><span>│     └── ansi-styles@4.3.0, ansi-styles@6.2.1</span></span>\n<span class=\"line\"><span>├── https://opencollective.com/unified</span></span>\n<span class=\"line\"><span>│   └── hast-util-from-html@2.0.1, hast-util-select@6.0.2, hast-util-has-property@3.0.0, hast-util-to-string@3.0.0, hastscript@9.0.0, mdast-util-directive@3.0.0, mdast-util-to-markdown@2.1.0, mdast-util-phrasing@4.1.0, mdast-util-to-string@4.0.0, rehype@13.0.1, rehype-parse@9.0.0, rehype-format@5.0.0, hast-util-embedded@3.0.0, hast-util-phrasing@3.0.1, hast-util-is-body-ok-link@3.0.0, html-whitespace-sensitive-tag-names@3.0.0, rehype-minify-whitespace@6.0.0, remark-directive@3.0.0, micromark-extension-directive@3.0.1, unified@11.0.5, unist-util-visit@5.0.0, vfile@6.0.3, @mdx-js/mdx@3.0.1, estree-util-build-jsx@3.0.1, estree-util-is-identifier-name@3.0.0, estree-util-to-js@2.0.0, hast-util-to-estree@3.1.0, estree-util-attach-comments@3.0.0, hast-util-whitespace@3.0.0, mdast-util-mdx-expression@2.0.0, mdast-util-mdx-jsx@3.1.3, vfile-message@4.0.2, mdast-util-mdxjs-esm@2.0.1, hast-util-to-jsx-runtime@2.3.0, remark-mdx@3.0.1, mdast-util-mdx@3.0.0, micromark-extension-mdxjs@3.0.0, micromark-extension-mdx-jsx@3.0.1, micromark-extension-mdx-md@2.0.0, micromark-extension-mdxjs-esm@3.0.0, unist-util-position-from-estree@2.0.0, estree-util-visit@2.0.0, hast-util-to-html@9.0.2, rehype-raw@7.0.0, hast-util-raw@9.0.4, hast-util-from-parse5@8.0.1, hastscript@8.0.0, hast-util-parse-selector@4.0.0, vfile-location@5.0.3, hast-util-to-parse5@8.0.0, remark-gfm@4.0.0, mdast-util-gfm@3.0.0, mdast-util-gfm-autolink-literal@2.0.1, mdast-util-find-and-replace@3.0.1, mdast-util-gfm-footnote@2.0.0, mdast-util-gfm-strikethrough@2.0.0, mdast-util-gfm-table@2.0.0, mdast-util-gfm-task-list-item@2.0.0, micromark-extension-gfm@3.0.0, micromark-extension-gfm-autolink-literal@2.1.0, micromark-extension-gfm-footnote@2.1.0, micromark-extension-gfm-strikethrough@2.1.0, micromark-extension-gfm-table@2.1.0, micromark-extension-gfm-tagfilter@2.0.0, micromark-extension-gfm-task-list-item@2.1.0, remark-stringify@11.0.0, hast-util-to-text@4.0.2, hast-util-is-element@3.0.0, unist-util-find-after@5.0.0, unist-util-is@6.0.0, mdast-util-definitions@6.0.0, rehype-stringify@10.0.0, remark-parse@11.0.0, mdast-util-from-markdown@2.0.1, unist-util-stringify-position@4.0.0, remark-rehype@11.1.0, mdast-util-to-hast@13.2.0, unist-util-position@5.0.0, unist-util-remove-position@5.0.0, unist-util-visit-parents@6.0.1, retext@9.0.0, retext-latin@4.0.0, nlcst-to-string@4.0.0, unist-util-modify-children@4.0.0, unist-util-visit-children@3.0.0, retext-stringify@4.0.0, retext-smartypants@6.1.1</span></span>\n<span class=\"line\"><span>├── https://locize.com</span></span>\n<span class=\"line\"><span>│   └── i18next@23.15.1</span></span>\n<span class=\"line\"><span>├── https://github.com/sponsors/antfu</span></span>\n<span class=\"line\"><span>│   └── oniguruma-to-js@0.3.3</span></span>\n<span class=\"line\"><span>├── https://github.com/sponsors/colinhacks</span></span>\n<span class=\"line\"><span>│   └── zod@3.23.8</span></span>\n<span class=\"line\"><span>├─┬ https://opencollective.com/postcss/</span></span>\n<span class=\"line\"><span>│ │ └── postcss@8.4.45, postcss-nested@6.2.0</span></span>\n<span class=\"line\"><span>│ └── https://github.com/sponsors/ai</span></span>\n<span class=\"line\"><span>│     └── nanoid@3.3.7</span></span>\n<span class=\"line\"><span>├── https://github.com/sponsors/isaacs</span></span>\n<span class=\"line\"><span>│   └── glob@7.2.3, rimraf@3.0.2, signal-exit@4.1.0, signal-exit@4.0.2</span></span>\n<span class=\"line\"><span>├─┬ https://opencollective.com/babel</span></span>\n<span class=\"line\"><span>│ │ └── @babel/core@7.25.2</span></span>\n<span class=\"line\"><span>│ └── https://opencollective.com/browserslist</span></span>\n<span class=\"line\"><span>│     └── browserslist@4.23.3, caniuse-lite@1.0.30001660, update-browserslist-db@1.1.0</span></span>\n<span class=\"line\"><span>├── https://github.com/sponsors/sibiraj-s</span></span>\n<span class=\"line\"><span>│   └── ci-info@4.0.0</span></span>\n<span class=\"line\"><span>├─┬ https://github.com/chalk/strip-ansi?sponsor=1</span></span>\n<span class=\"line\"><span>│ │ └── strip-ansi@7.1.0</span></span>\n<span class=\"line\"><span>│ └── https://github.com/chalk/ansi-regex?sponsor=1</span></span>\n<span class=\"line\"><span>│     └── ansi-regex@6.1.0</span></span>\n<span class=\"line\"><span>├── https://github.com/vitejs/vite?sponsor=1</span></span>\n<span class=\"line\"><span>│   └── vite@5.4.6</span></span>\n<span class=\"line\"><span>├── https://opencollective.com/libvips</span></span>\n<span class=\"line\"><span>│   └── sharp@0.33.5, @img/sharp-darwin-arm64@0.33.5, @img/sharp-libvips-darwin-arm64@1.0.4</span></span>\n<span class=\"line\"><span>├─┬ https://github.com/sponsors/fb55</span></span>\n<span class=\"line\"><span>│ │ └── css-select@5.1.0, css-what@6.1.0, domelementtype@2.3.0</span></span>\n<span class=\"line\"><span>│ ├── https://github.com/fb55/domhandler?sponsor=1</span></span>\n<span class=\"line\"><span>│ │   └── domhandler@5.0.3</span></span>\n<span class=\"line\"><span>│ └─┬ https://github.com/fb55/domutils?sponsor=1</span></span>\n<span class=\"line\"><span>│   │ └── domutils@3.1.0</span></span>\n<span class=\"line\"><span>│   └── https://github.com/cheeriojs/dom-serializer?sponsor=1</span></span>\n<span class=\"line\"><span>│       └── dom-serializer@2.0.0</span></span>\n<span class=\"line\"><span>├── https://github.com/fb55/htmlparser2?sponsor=1</span></span>\n<span class=\"line\"><span>│   └── htmlparser2@8.0.2</span></span>\n<span class=\"line\"><span>├── https://github.com/sponsors/NaturalIntelligence</span></span>\n<span class=\"line\"><span>│   └── fast-xml-parser@4.5.0</span></span>\n<span class=\"line\"><span>├─┬ https://github.com/privatenumber/get-tsconfig?sponsor=1</span></span>\n<span class=\"line\"><span>│ │ └── get-tsconfig@4.8.1</span></span>\n<span class=\"line\"><span>│ └── https://github.com/privatenumber/resolve-pkg-maps?sponsor=1</span></span>\n<span class=\"line\"><span>│     └── resolve-pkg-maps@1.0.0</span></span>\n<span class=\"line\"><span>└── https://github.com/sponsors/ljharb</span></span>\n<span class=\"line\"><span>    └── minimist@1.2.8</span></span></code></pre>\n<p>As stated in the <a href=\"https://docs.npmjs.com/cli/commands/npm-fund\">official npm documentation</a>, the <code>npm fund</code> command shows funding information for the installed packages in your project.</p>\n<p>And there can be a lot of them!</p>\n<p>But you might wonder, how can you add funding information to your own project? It can be interesting to let know the world that you are looking for funding, right?</p>\n<h2 id=\"adding-funding-links-to-your-packagejson\">Adding Funding Links to Your <code>package.json</code></h2>\n<p>It’s quite simple in fact. You can add funding information to your <code>package.json</code> file by using the <a href=\"https://docs.npmjs.com/cli/v10/configuring-npm/package-json#funding\"><code>funding</code> field</a>.</p>\n<p>As stated in the official npm documentation:</p>\n<blockquote>\n<p>You can specify an object containing a URL that provides up-to-date information about ways to help fund development of your package, a string URL, or an array of objects and string URLs:</p>\n</blockquote>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"json\"><code><span class=\"line\"><span style=\"color:#E6E8EC\">{</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t&quot;</span><span style=\"color:#8FE1E6\">funding</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#E6E8EC\">: [</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t\t{</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t\t\t&quot;</span><span style=\"color:#8FE1E6\">type</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#F083A7\">individual</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#E6E8EC\">,</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t\t\t&quot;</span><span style=\"color:#8FE1E6\">url</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#F083A7\">http://example.com/donate</span><span style=\"color:#E6E8EC\">&quot;</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t\t},</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t\t&quot;</span><span style=\"color:#F083A7\">http://example.com/donateAlso</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#E6E8EC\">,</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t\t{</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t\t\t&quot;</span><span style=\"color:#8FE1E6\">type</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#F083A7\">patreon</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#E6E8EC\">,</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t\t\t&quot;</span><span style=\"color:#8FE1E6\">url</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#F083A7\">https://www.patreon.com/my-account</span><span style=\"color:#E6E8EC\">&quot;</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t\t}</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t]</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">}</span></span></code></pre>\n<p>From there, those who install your package might see the funding information when they run some npm commands. And who knows, they might decide to support your project!</p>\n<p>On top of that, if your package is listed on the npm registry, the funding information will be displayed on the package’s page with a “Fund this package” button:</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/add-funding-links-to-your-package.json.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/add-funding-links-to-your-package.json.png\" alt=\"Screenshot the 'Fund this package' npm registry button\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"370\" height=\"50\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"Screenshot the 'Fund this package' npm registry button\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/add-funding-links-to-your-package.json.png\" alt=\"Screenshot the 'Fund this package' npm registry button\" width=\"370\" height=\"50\" data-astro-cid-lanmunwp></dialog></div>\n<hr/>\n<p><strong>Funding your open-source project might be complicated</strong>, but referencing your funding links a the right places can make it easier for people to support you. And adding funding links to your <code>package.json</code> file is a good start! It’s not going to make hundreds of people support you, for sure, but it’s a good way to let the world know that you are looking for funding; <strong>and little by little, you might get a coffee or two out of it!</strong></p>",
      "date_published": "2024-09-22T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "npm",
        "Funding",
        "Tutorial"
      ]
    },
    {
      "id": "https://openresource.dev/articles/get-real-time-github-stars-notifications-in-discord/",
      "url": "https://openresource.dev/articles/get-real-time-github-stars-notifications-in-discord/",
      "title": "Get Real-Time GitHub Stars Notifications in Discord",
      "summary": "Want instant updates when your GitHub repository gets new stars? Set up an easy GitHub Actions workflow to send notifications directly to Discord!",
      "content_html": "<p class=\"lead\">After the refactoring of this website, folks (maybe you) started to spread the word about it. The statistics started to rise a little bit, and we discovered along the way that the repository holding this website also started to receive some new stars. To our knowledge, there’s no native way to get notified by GitHub when you receive stars on your repositories. So, we decided to do something about it!</p>\n<p>We know, we know, tracking stars is a little bit linked to the gamification of the open source world, but to be honest, it’s still a fun way to keep track of your project’s popularity and engage with your community.</p>\n<p>So, we decided to build a simple automation that would send a notification to a private Discord channel whenever our GitHub repository receives new stars. There are probably better ways to do this, existing solutions, but where is the fun in that?</p>\n<p>After a few times of tweaking and testing, we finally got it working! 🎉</p>\n<p>Here is the notification we received on our phone this afternoon:</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/get-real-time-github-stars-notifications-in-discord-1.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/get-real-time-github-stars-notifications-in-discord-1.png\" alt=\"A phone notification from GitHub Stars Bot in the Open {re}Source Discord: 'The repository has gained new stars! 60 → 61'.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"458\" height=\"133\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"A phone notification from GitHub Stars Bot in the Open {re}Source Discord: 'The repository has gained new stars! 60 → 61'.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/get-real-time-github-stars-notifications-in-discord-1.png\" alt=\"A phone notification from GitHub Stars Bot in the Open {re}Source Discord: 'The repository has gained new stars! 60 → 61'.\" width=\"458\" height=\"133\" data-astro-cid-lanmunwp></dialog></div>\n<p>And when you click on the notification, here is how the notification appears on Discord, showing the new star count and the repository name:</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/get-real-time-github-stars-notifications-in-discord-2.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/get-real-time-github-stars-notifications-in-discord-2.png\" alt=\"GitHub Stars Bot's message in Discord, with a star avatar: 'The repository has gained new stars! Previous: 60 → Total: 61'.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"458\" height=\"166\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"GitHub Stars Bot's message in Discord, with a star avatar: 'The repository has gained new stars! Previous: 60 → Total: 61'.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/get-real-time-github-stars-notifications-in-discord-2.png\" alt=\"GitHub Stars Bot's message in Discord, with a star avatar: 'The repository has gained new stars! Previous: 60 → Total: 61'.\" width=\"458\" height=\"166\" data-astro-cid-lanmunwp></dialog></div>\n<p><strong>Cool, right? Here’s how it’s been done!</strong></p>\n<h2 id=\"step-1-create-a-discord-webhook\">Step 1: Create a Discord Webhook</h2>\n<p>To send notifications to Discord, you will need to set up a webhook in your Discord server. Here’s how to do it:</p>\n<ol>\n<li>Open your Discord server and navigate to the channel where you want to receive notifications. You can create a dedicated private channel for this purpose.</li>\n<li>Click on the gear icon next to the channel name to access the channel settings.</li>\n<li>Select the “Integrations” tab.</li>\n<li>Click on “Webhooks” and then “Create Webhook.”</li>\n<li>Give your webhook a name (e.g. “GitHub Stars Bot”), and select a nice image.</li>\n<li><strong>Copy the webhook URL, as you will need it later.</strong></li>\n</ol>\n<p>Here’s also a link to the <a href=\"https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks\">Discord documentation - Intro to Webhooks</a> for more information.</p>\n<h2 id=\"step-2-create-a-github-repository\">Step 2: Create a GitHub Repository</h2>\n<p>Now, let’s create a private GitHub repository to store our future GitHub Actions workflow. You can create a new repository or use an existing one, make it public or private, as you prefer.</p>\n<h2 id=\"step-3-create-a-secret-variable-in-github\">Step 3: Create a Secret Variable in GitHub</h2>\n<p>To securely store your Discord Webhook URL to ensure that sensitive data isn’t exposed in your repository code, you will need to create a secret variable in your GitHub repository:</p>\n<ol>\n<li>Go to your GitHub repository and click on the “Settings” tab.</li>\n<li>In the left sidebar, click on “Secrets and variables” and then “Actions.”</li>\n<li>Click on the “New repository secret” button.</li>\n<li>Name your secret <code>DISCORD_WEBHOOK_URL</code> and paste the webhook URL you copied from Discord.</li>\n</ol>\n<h2 id=\"step-4-create-a-github-actions-workflow\">Step 4: Create a GitHub Actions Workflow</h2>\n<blockquote>\n<p>[!NOTE] What is GitHub Actions?\nIf you’re not familiar with GitHub Actions, it allows you to automate workflows directly in your GitHub repository, and it can be triggered based on various events. More information can be found in the <a href=\"https://docs.github.com/en/actions\">GitHub Actions documentation</a>.</p>\n</blockquote>\n<p>In this repository:</p>\n<ol>\n<li>Create a new directory called <code>.github/workflows</code>.</li>\n<li>Create a new file called for instance <code>gh-stars-to-discord.yml</code> (or choose a name you prefer).</li>\n</ol>\n<h3 id=\"the-algorithm\">The Algorithm</h3>\n<p>The algorithm is rather simple:</p>\n<ul>\n<li>Every hour, the workflow will check the current number of stars on the repository using the GitHub API.</li>\n<li>While doing so, it will also check the rate limit of the API.\n<ul>\n<li>If the rate limit is low, the workflow will stop.</li>\n<li>If not, it will compare the current number of stars with the previous number of stars.</li>\n</ul>\n</li>\n<li>If there are new stars, it will send a notification to Discord using the webhook URL.</li>\n<li>Finally, it will save the current number of stars for the next comparison.</li>\n</ul>\n<h3 id=\"using-the-github-api\">Using the GitHub API</h3>\n<p>To get started, you will need to use the <a href=\"https://docs.github.com/en/rest\">GitHub REST API</a> to fetch the star count for your repository. The GitHub API provides a simple way to access information about your repositories, including the number of stars they have received.</p>\n<p>There is a public endpoint that you can use to get the star count for a specific repository:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>GET https://api.github.com/repos/{owner}/{repo}</span></span></code></pre>\n<p>Replace <code>{owner}</code> with your GitHub username and <code>{repo}</code> with the name of your repository. The response will include a JSON object with various details about the repository, including the <code>stargazers_count</code> field, which indicates the number of stars.</p>\n<p>So for our main repository, you would make a request to:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>GET https://api.github.com/repos/Open-reSource/openresource.dev</span></span></code></pre>\n<blockquote>\n<p>[!NOTE] Try it out!\nYou can try it out directly in your browser (or using a tool like <a href=\"https://github.com/curl/curl\">Curl</a>) to see the JSON response. In the browser, you can simply paste the URL into the address bar and hit enter.</p>\n</blockquote>\n<p>In September 2024, when this article was written, the Open {re}Source main repository had 61 stars, so the answer was:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"json\"><code><span class=\"line\"><span style=\"color:#E6E8EC\">{</span></span>\n<span class=\"line\"><span style=\"color:#8F929A;font-style:italic\">\t// ...</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t&quot;</span><span style=\"color:#8FE1E6\">stargazers_count</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#C78FEF\">61</span></span>\n<span class=\"line\"><span style=\"color:#8F929A;font-style:italic\">\t// ...</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">}</span></span></code></pre>\n<blockquote>\n<p>[!WARNING] Be mindful of the GitHub API rate limits\nBe mindful of the GitHub API rate limits when making requests. You can find more information about the rate limits in the <a href=\"https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting\">GitHub API documentation</a>.</p>\n<p>As of September 2026, the GitHub API allows for up to 60 requests per hour for unauthenticated requests and up to 5,000 requests per hour for authenticated requests. If you plan to make frequent requests, consider using a personal access token for authentication.</p>\n</blockquote>\n<h3 id=\"the-actual-workflow\">The Actual Workflow</h3>\n<p>Now, let’s create the actual workflow:</p>\n<ol>\n<li>Clone your repository to your local machine or edit it directly on GitHub.</li>\n<li>Add the following YAML code to your <code>gh-stars-to-discord.yml</code> file:</li>\n</ol>\n<blockquote>\n<p>[!NOTE]</p>\n<ul>\n<li>Make sure to replace <code>open-reSource/openresource.dev</code> with your own repository name.</li>\n<li>The workflow is set to run every hour, but you can adjust the schedule as needed by changing the <code>cron</code> expression.</li>\n<li>You can change the text of the notification sent to Discord by modifying the <code>curl</code> command in the <code>Compare and notify if new stars</code> step.</li>\n</ul>\n</blockquote>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"yaml\"><code><span class=\"line\"><span style=\"color:#3AB9BF\">name</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">GitHub Stars to Discord</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#C78FEF\">on</span><span style=\"color:#E6E8EC\">:</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">  schedule</span><span style=\"color:#E6E8EC\">:</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">    - </span><span style=\"color:#3AB9BF\">cron</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#E6E8EC\">&#39;</span><span style=\"color:#F083A7\">0 * * * *</span><span style=\"color:#E6E8EC\">&#39;</span><span style=\"color:#8F929A;font-style:italic\"> # Every 1 hour. You can change the frequency as needed.</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">  workflow_dispatch</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#8F929A;font-style:italic\"># Allows manual triggering</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">env</span><span style=\"color:#E6E8EC\">:</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">  DISCORD_WEBHOOK_URL</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">${{ secrets.DISCORD_WEBHOOK_URL }}</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">  GITHUB_REPOSITORY</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#E6E8EC\">&#39;</span><span style=\"color:#F083A7\">open-reSource/openresource.dev</span><span style=\"color:#E6E8EC\">&#39;</span><span style=\"color:#8F929A;font-style:italic\"> # Change this to your repository</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">jobs</span><span style=\"color:#E6E8EC\">:</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">  notify</span><span style=\"color:#E6E8EC\">:</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">    runs-on</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">ubuntu-latest</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">    steps</span><span style=\"color:#E6E8EC\">:</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">      - </span><span style=\"color:#3AB9BF\">name</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">Get the current number of stars and check rate limit</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        id</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">get_stars</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        run</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#83ACEF\">|</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          response=$(curl -s -i https://api.github.com/repos/${{ env.GITHUB_REPOSITORY }})</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          stars=$(echo &quot;$response&quot; | grep -oP &#39;&quot;stargazers_count&quot;:\\s*\\K\\d+&#39;)</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          rate_limit_remaining=$(echo &quot;$response&quot; | grep -Fi &#39;X-RateLimit-Remaining:&#39; | awk -F&#39;: &#39; &#39;{print $2}&#39; | tr -d &#39;\\r&#39;)</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          echo &quot;Current stars: $stars&quot;</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          echo &quot;Rate limit remaining: $rate_limit_remaining&quot;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          echo &quot;stars=$stars&quot; &gt;&gt; $GITHUB_OUTPUT</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          echo &quot;rate_limit_remaining=$rate_limit_remaining&quot; &gt;&gt; $GITHUB_OUTPUT</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">      - </span><span style=\"color:#3AB9BF\">name</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">Stop if rate limit is low</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        if</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">${{ steps.get_stars.outputs.rate_limit_remaining &lt; 10 }}</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        run</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#83ACEF\">|</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          echo &quot;Rate limit is low, exiting&quot;</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          exit 1</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">      - </span><span style=\"color:#3AB9BF\">name</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">Cache previous stars count</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        id</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">cache_previous_stars</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        uses</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">actions/cache@v4</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        with</span><span style=\"color:#E6E8EC\">:</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">          path</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">previous_stars.txt</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">          key</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">stars-${{ github.repository }}-${{ github.run_id }}</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">          restore-keys</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#83ACEF\">|</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">            stars-${{ github.repository }}-</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">      - </span><span style=\"color:#3AB9BF\">name</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">Load the previous number of stars</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        id</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">load_previous_stars</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        run</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#83ACEF\">|</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          if [ -f previous_stars.txt ]; then</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">            echo &quot;Loading previous stars&quot;</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">            PREVIOUS_STARS=$(cat previous_stars.txt)</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          else</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">            echo &quot;No previous stars found&quot;</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">            PREVIOUS_STARS=0</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          fi</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          echo &quot;Previous stars: $PREVIOUS_STARS&quot;</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          echo &quot;previous_stars=$PREVIOUS_STARS&quot; &gt;&gt; $GITHUB_OUTPUT</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">      - </span><span style=\"color:#3AB9BF\">name</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">Compare and notify if new stars</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        if</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">${{ steps.get_stars.outputs.stars != steps.load_previous_stars.outputs.previous_stars }}</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        run</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#83ACEF\">|</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          NEW_STARS=${{ steps.get_stars.outputs.stars }}</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          PREVIOUS_STARS=${{ steps.load_previous_stars.outputs.previous_stars }}</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          if [ $NEW_STARS -gt $PREVIOUS_STARS ]; then</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">            echo &quot;There are new stars: $NEW_STARS stars (previous: $PREVIOUS_STARS)&quot;</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">            curl -H &quot;Content-Type: application/json&quot; \\</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">              -d &quot;{\\&quot;content\\&quot;: \\&quot;The repository has gained new stars! Previous: $PREVIOUS_STARS → Total: $NEW_STARS\\&quot;}&quot; \\</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">              ${DISCORD_WEBHOOK_URL}</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          else</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">            echo &quot;No new stars&quot;</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          fi</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">      - </span><span style=\"color:#3AB9BF\">name</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">Save current stars count</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        run</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#83ACEF\">|</span></span>\n<span class=\"line\"><span style=\"color:#F083A7\">          echo &quot;${{ steps.get_stars.outputs.stars }}&quot; &gt; previous_stars.txt</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">      - </span><span style=\"color:#3AB9BF\">name</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">Update cache with new stars count</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        uses</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">actions/cache@v4</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">        with</span><span style=\"color:#E6E8EC\">:</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">          path</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">previous_stars.txt</span></span>\n<span class=\"line\"><span style=\"color:#3AB9BF\">          key</span><span style=\"color:#E6E8EC\">: </span><span style=\"color:#F083A7\">stars-${{ github.repository }}-${{ github.run_id }}</span></span></code></pre>\n<h2 id=\"step-5-run-the-workflow\">Step 5: Run the Workflow</h2>\n<p>The workflow has a <code>workflow_dispatch</code> trigger, which means you can run it manually from the GitHub Actions tab in your repository. You can also wait for the next scheduled run (every hour) to see it in action.</p>\n<p>The first time you run the workflow, it will probably send a notification saying that you had 0 stars and now you have X stars (the current number of stars).</p>\n<blockquote>\n<p>[!NOTE]\nWe voluntarily left some logging in the workflow to help you debug if needed. You can remove or comment out the <code>echo</code> statements if you want to clean up the logs.</p>\n<p>To check the logs, once your YAML file is pushed to the repository, go to the “Actions” tab, select the workflow, and click on the latest run. All the logs will be displayed there.</p>\n</blockquote>\n<p>To be honest, we are a little bit lazy, so we didn’t implement a complex logic to handle this first run, or even when the count of stars decreases. But you can always improve the workflow to suit your needs! This is just a starting point.</p>\n<hr/>\n<p><strong>Automation is really cool!</strong> You could do the same thing for your followers in your GitHub profile, send notifications by email, Slack, etc. But automation is not limited to just notifications. You can also automate tasks like deploying your code, running tests, and much more.</p>\n<p><strong>The possibilities are endless!</strong></p>\n<p>A few words before we finish:</p>\n<ul>\n<li><strong>Want to spam us with stars?</strong> You can add some stars to <a href=\"https://github.com/Open-reSource/openresource.dev\">https://github.com/Open-reSource/openresource.dev</a>. We will be happy to get some notifications on our mobile phones!</li>\n<li>Please let us know if you’d like to see more automation tutorials like this one!</li>\n<li>We haven’t created a reusable workflow, shared it in the Marketplace, nor created a GitHub Gist. We thought it was easier just to share a little bit of code in this article that you could start from and adapt. If you want it to be stored somewhere with a more formal MIT license, please let us know! But please feel free to use it as you wish.</li>\n</ul>\n<p><strong>Happy coding! 🎉</strong></p>",
      "date_published": "2024-09-17T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "Automation",
        "Discord",
        "Discord Webhook",
        "GitHub",
        "GitHub Actions",
        "GitHub API",
        "GitHub Stars"
      ]
    },
    {
      "id": "https://openresource.dev/articles/bluesky-starter-pack/",
      "url": "https://openresource.dev/articles/bluesky-starter-pack/",
      "title": "Bluesky Starter Pack About Open Source",
      "summary": "Open {re}Source creates a Bluesky starter pack about open source",
      "content_html": "<p class=\"lead\">Bluesky released starter packs on June 26, 2024. They are personalized invites that allow users to bring people directly into your slice of Bluesky!</p>\n<p><a href=\"https://bsky.social\">Bluesky</a>, the decentralized social media platform, <a href=\"https://bsky.social/about/blog/06-26-2024-starter-packs\">introduced starter packs on June 26, 2024</a>, aiming to personalize user experiences and make it easier for communities to grow. They let users bring friends directly into their customized Bluesky environment.</p>\n<h2 id=\"whats-in-a-bluesky-starter-pack\">What’s in a Bluesky Starter Pack?</h2>\n<p>A Bluesky starter pack can include the following:</p>\n<ul>\n<li><strong>Custom feeds</strong>: On Bluesky, you can set any algorithm or topic as your home timeline.</li>\n<li><strong>Recommended follows</strong>: Add your favorite accounts and encourage new users to follow them.</li>\n</ul>\n<p>As of September 2026:</p>\n<ul>\n<li><strong>Starter packs show up in search</strong>, in the “Starter Packs” tab. At launch they didn’t, and a link or an embed preview was the only way in.</li>\n<li><strong>Starter packs can recommend up to 500 people and up to 3 custom feeds</strong>. The limit was 150 people at launch. New users will automatically have Following and Discover pinned.</li>\n</ul>\n<h2 id=\"the-open-source-bluesky-starter-pack\">The Open Source Bluesky Starter Pack</h2>\n<p>You can count on us! The Open {re}Source team is excited to introduce <strong>our very own Bluesky starter pack focused on open source</strong>! 🚀</p>\n<p>We followed the tutorial provided by Bluesky <a href=\"https://bsky.social/about/blog/06-26-2024-starter-packs\">in their blog post</a>, but even without the tutorial, it is quite easy and intuitive to create a starter pack from the interface.</p>\n<p>Below is the link to our open source Bluesky starter pack:</p>\n<a href=\"https://go.bsky.app/BrzaZ72\" style=\"display: flex; margin-top: 20px; margin-bottom: 20px\"><div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/bluesky-starter-pack.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/bluesky-starter-pack.png\" alt=\"Go to the Open {re}Source Bluesky starter pack\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"430\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"Go to the Open {re}Source Bluesky starter pack\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/bluesky-starter-pack.png\" alt=\"Go to the Open {re}Source Bluesky starter pack\" width=\"300\" height=\"430\" data-astro-cid-lanmunwp></dialog></div></a>\n<p>It contains accounts and individuals linked to the open-source world, as well as <a href=\"https://bsky.app/profile/did:plc:7qnsmqeluaybzzdfuaic4ulf/feed/aaaitsh7hqhew\">the Open Source feed we created for Bluesky</a>.</p>\n<h2 id=\"get-involved\">Get Involved!</h2>\n<p>We hope you enjoy our starter pack! 🎉</p>\n<p>Don’t hesitate to share your feedback <a href=\"https://bsky.app/profile/openresource.dev\">with us on Bluesky</a>, suggest new accounts to follow, or even create your own starter pack and share it with us! 🙌</p>\n<div class=\"bsky-container\" data-astro-cid-fpx3rh32><bsky-widget data-handle=\"openresource.dev\" data-astro-cid-fpx3rh32=\"true\"> </bsky-widget></div>\n<p>Find this Bluesky profile widget cool? Check this out:</p>\n<a class=\"entry not-content\" href=\"https://github.com/saurabhdaware/bsky-widget\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/30949385?v=4&amp;s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3><span class=\"owner\">saurabhdaware/</span><br/>bsky-widget</span><span class=\"description\" data-astro-cid-jxjoqtw3>Unofficial Bluesky widget to render cute profile cards in your websites ^_^</span></span></a>\n<hr/>\n<p>Bluesky’s starter packs are an excellent way to foster community and personalize your social media experience. The Open {re}Source Bluesky starter pack is designed to connect you with the open-source community on Bluesky. Join us, and let’s continue to build and share together!</p>\n<p>Feel free to reach out with any questions or suggestions. Happy Blueskying! 🚀</p>",
      "date_published": "2024-07-01T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "Bluesky",
        "Social Media",
        "Tools"
      ]
    },
    {
      "id": "https://openresource.dev/articles/github-ghost-user/",
      "url": "https://openresource.dev/articles/github-ghost-user/",
      "title": "Who Is the Ghost User on GitHub?",
      "summary": "Learn who is the ghost user on GitHub and why it can appear in some issues, discussions, or pull requests.",
      "content_html": "<p class=\"lead\">This morning, I woke up to a storm of 200+ GitHub notifications. My inbox, usually pristine, was drowning in a deluge of spams.</p>\n<p>As I scrolled through, my screen filled with an overwhelming array of spam discussions.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/github-ghost-user-1.webp\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/github-ghost-user-1.webp\" alt=\"A spam GitHub discussion titled 'WATCH Kingdom of the Planet of the Apes FuLLMovie', with Watch now and Download buttons.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"570\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"A spam GitHub discussion titled 'WATCH Kingdom of the Planet of the Apes FuLLMovie', with Watch now and Download buttons.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/github-ghost-user-1.webp\" alt=\"A spam GitHub discussion titled 'WATCH Kingdom of the Planet of the Apes FuLLMovie', with Watch now and Download buttons.\" width=\"720\" height=\"570\" data-astro-cid-lanmunwp></dialog></div>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/github-ghost-user-2.webp\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/github-ghost-user-2.webp\" alt=\"A spam GitHub discussion titled 'FREE-ROBUX-GENERATOR-2024-FREE-ROBUX-NEW-CODES-DAILY BONUS', with links to get them.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"386\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"A spam GitHub discussion titled 'FREE-ROBUX-GENERATOR-2024-FREE-ROBUX-NEW-CODES-DAILY BONUS', with links to get them.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/github-ghost-user-2.webp\" alt=\"A spam GitHub discussion titled 'FREE-ROBUX-GENERATOR-2024-FREE-ROBUX-NEW-CODES-DAILY BONUS', with links to get them.\" width=\"720\" height=\"386\" data-astro-cid-lanmunwp></dialog></div>\n<p><strong>OK, cool, we are being productive today! 200+ GitHub discussions to delete!</strong></p>\n<p>We can’t see it in the screenshots, but there were several authors of the discussions, or answering to the discussions. I couldn’t block them for this specific repository as I am not the owner of the repository, but I could report them. So, one by one, I started to delete the discussions and report the users without looking at their profile.</p>\n<p>The usual process happened on GitHub side, except for one user: <a href=\"https://github.com/ghost\">ghost</a>!</p>\n<p>The GitHub Developer Support answered:</p>\n<blockquote>\n<p>“The <strong>ghost</strong> username is in place to designate accounts that have been deleted by their owners, but that still have content that is visible across the GitHub platform.”</p>\n</blockquote>\n<p><strong>Oops!</strong></p>\n<p>Indeed, I didn’t check the GitHub profile of the user before reporting it, and it is pretty obvious when you are looking at it:</p>\n<a class=\"entry not-content\" href=\"https://github.com/ghost\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/10137?s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3>ghost</span><span class=\"description\" data-astro-cid-jxjoqtw3>Hi, I'm <a href='https://github.com/ghost'>@ghost</a>! I take the place of user accounts that have been deleted. 👻</span></span></a>\n<p>The ghost user is a placeholder account used by GitHub to manage contributions and commits from users who have been deleted or whose accounts are no longer active. So it is not a spam account, and not especially an account to report. 😅</p>\n<p>When a user is deleted from GitHub, their contributions, such as commits, issues, and comments, are not erased. Instead, these contributions are attributed to the Ghost user to maintain the integrity and history of the repository.</p>\n<h2 id=\"the-role-of-the-ghost-user\">The Role of the Ghost User</h2>\n<p>The primary purpose of the ghost user is to preserve the history and context of projects.</p>\n<p>It helps with <strong>maintaining repository integrity</strong>. When a user is deleted, removing their contributions would disrupt the continuity and understanding of the project. By attributing these contributions to the ghost user, GitHub ensures that the project’s history remains intact.</p>\n<p>It also helps with <strong>contextual continuity</strong>. Comments on issues and pull requests often provide valuable insights and discussions. Reassigning these to the ghost user ensures that future contributors can still benefit from these historical discussions.</p>\n<h2 id=\"when-does-the-ghost-user-appear\">When Does the Ghost User Appear?</h2>\n<p>You might see the ghost user <strong>when a GitHub user decides to delete their account</strong>, all their contributions are transferred to the Ghost user.</p>\n<p>It can also happen when <strong>GitHub removes an account</strong> due to policy violations or other reasons. In this case, the contributions are reassigned to the Ghost user.</p>\n<hr/>\n<p>You can even follow it: 13k people do (as of September 2026). 😅</p>",
      "date_published": "2024-05-18T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "GitHub"
      ]
    },
    {
      "id": "https://openresource.dev/articles/contrib-rocks/",
      "url": "https://openresource.dev/articles/contrib-rocks/",
      "title": "contrib.rocks: Generate an Image of GitHub Repositories Top Contributors",
      "summary": "contrib.rocks generates an image of GitHub repositories top contributors.",
      "content_html": "<p class=\"lead\"><a href=\"https://contrib.rocks/\">contrib.rocks</a> is a an online tool that generates an image of the top contributors of a GitHub repository that can be embedded in any website or Markdown file; including its README file.</p>\n<p>It is completely free and maintained by Suguru Inatomi, a.k.a. <a href=\"https://github.com/lacolaco\">lacolaco</a>. The source code is available on GitHub:</p>\n<a class=\"entry not-content\" href=\"https://github.com/lacolaco/contributors-img\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/1529180?v=4&amp;s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3><span class=\"owner\">lacolaco/</span><br/>contributors-img</span><span class=\"description\" data-astro-cid-jxjoqtw3></span></span></a>\n<p>This service allows to give a visual representation of the top contributors of any GitHub repository.</p>\n<p>Generating such an image of your GitHub repository top contributors can be a great way to show the activity of your GitHub repository and encourage people to contribute, but also to celebrate your top contributors.</p>\n<h2 id=\"how-to-use\">How to Use</h2>\n<p>Usage is pretty straightforward:</p>\n<ol>\n<li>Go to <a href=\"https://contrib.rocks/\">https://contrib.rocks/</a></li>\n<li>Enter a GitHub repository (e.g., <code>open-reSource/openresource.dev</code>)</li>\n</ol>\n<p>And that’s it! You will get the image representing the top contributors of the GitHub repository you entered.</p>\n<p>Then, you can click on the “Get Image URL!” button to get the Markdown code to embed the image in your README file for instance.</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"md\"><code><span class=\"line\"><span style=\"color:#E6E8EC\">&lt;a href=&quot;https://github.com/open-reSource/openresource.dev/graphs/contributors&quot;&gt;</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">  &lt;img src=&quot;https://contrib.rocks/image?repo=open-reSource/openresource.dev&quot; /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">&lt;/a&gt;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">Made with [</span><span style=\"color:#3AB9BF\">contrib.rocks</span><span style=\"color:#E6E8EC\">](</span><span style=\"color:#3AB9BF\">https://contrib.rocks</span><span style=\"color:#E6E8EC\">).</span></span></code></pre>\n<p>You will notice that the first part of the generated Markdown code is in reality HTML code. You can use this HTML code to embed the image in any website or Markdown file.</p>\n<h2 id=\"rendering\">Rendering</h2>\n<p>Here is what it looks like for our <a href=\"https://github.com/Open-reSource/openresource.dev\">openresource.dev GitHub repository</a>:</p>\n<hr/>\n<a href=\"https://github.com/open-reSource/openresource.dev/graphs/contributors\"><img src=\"https://contrib.rocks/image?repo=open-reSource/openresource.dev\"/></a>\n<p>Made with <a href=\"https://contrib.rocks\">contrib.rocks</a>.</p>\n<hr/>\n<p>And here is the same rendering, but on a more active repository like <a href=\"https://github.com/godotengine/godot\">godot</a>:</p>\n<a class=\"entry not-content\" href=\"https://github.com/godotengine/godot\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/6318500?v=4&amp;s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3><span class=\"owner\">godotengine/</span><br/>godot</span><span class=\"description\" data-astro-cid-jxjoqtw3>Godot Engine – Multi-platform 2D and 3D game engine</span></span></a>\n<hr/>\n<a href=\"https://github.com/godotengine/godot/graphs/contributors\"><img src=\"https://contrib.rocks/image?repo=godotengine/godot\"/></a>\n<p>Made with <a href=\"https://contrib.rocks\">contrib.rocks</a>.</p>\n<hr/>\n<p>Some parameters can be added to the URL to customize the image:</p>\n<ul>\n<li><code>max={number}</code>: Max contributor count (100 by default)</li>\n<li><code>columns={number}</code>: Max columns (12 by default)</li>\n<li><code>anon={0|1}</code>: Include anonymous users (false by default)</li>\n</ul>\n<p>So if we add <code>&amp;max=10&amp;columns=2</code> to the image URL <code>https://contrib.rocks/image?repo=godotengine/godot</code> we get the following image with only the top 10 contributors and 2 columns:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"md\"><code><span class=\"line\"><span style=\"color:#E6E8EC\">&lt;a href=&quot;https://github.com/godotengine/godot/graphs/contributors&quot;&gt;</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">  &lt;img src=&quot;https://contrib.rocks/image?repo=godotengine/godot&amp;max=10&amp;columns=2&quot; /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">&lt;/a&gt;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">Made with [</span><span style=\"color:#3AB9BF\">contrib.rocks</span><span style=\"color:#E6E8EC\">](</span><span style=\"color:#3AB9BF\">https://contrib.rocks</span><span style=\"color:#E6E8EC\">).</span></span></code></pre>\n<hr/>\n<a href=\"https://github.com/godotengine/godot/graphs/contributors\"><img src=\"https://contrib.rocks/image?repo=godotengine/godot&amp;max=10&amp;columns=2\"/></a>\n<p>Made with <a href=\"https://contrib.rocks\">contrib.rocks</a>.</p>",
      "date_published": "2024-04-27T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "GitHub",
        "Markdown",
        "Readme",
        "Tools"
      ]
    },
    {
      "id": "https://openresource.dev/articles/repobeats/",
      "url": "https://openresource.dev/articles/repobeats/",
      "title": "Repobeats: GitHub README analytics",
      "summary": "Repobeats is a tool that provides analytics for your GitHub README files.",
      "content_html": "<p class=\"lead\"><a href=\"https://repobeats.axiom.co/\">Repobeats</a> is a tool that provides analytics of a GitHub repository that can be embedded in any Markdown file; including its README file.</p>\n<p>It is completely free and maintained by <a href=\"https://axiom.co/\">axiom.com</a>, but does not seem to be an open-source project as it is not referenced in <a href=\"https://github.com/axiomhq\">github.com/axiomhq</a>.</p>\n<p>This service allows to give a visual representation of the activity of your GitHub repository:</p>\n<ul>\n<li>the number of contributions in the last 30 days</li>\n<li>the number of opened/closed issues ratio with an associated bar chart of the past month</li>\n<li>the number of PRs opened with an associated bar chart of the past month</li>\n<li>the number of commits with an associated bar chart of the past month</li>\n<li>the top contributors with their GitHub green square activity; their contribution heatmap</li>\n</ul>\n<p>It can be a great way to show the activity of your GitHub repository and encourage people to contribute, but also to celebrate your top contributors.</p>\n<p>Behind the scene, Repobeats uses public data available on GitHub.</p>\n<h2 id=\"installation\">Installation</h2>\n<p>Installing Repobeats requires a GitHub account.</p>\n<blockquote>\n<p>[!WARNING]\nPlease consult their <a href=\"https://repobeats.axiom.co/\">Frequently Asked Questions</a> for more information before installing it. They explain for example how they use your email address.</p>\n</blockquote>\n<p>To install Repobeats, it is pretty straightforward:</p>\n<ol>\n<li>Go to <a href=\"https://repobeats.axiom.co/\">https://repobeats.axiom.co/</a></li>\n<li>Login with your GitHub account</li>\n<li>Select the owner and repository you want to analyze</li>\n</ol>\n<p>And that’s it! You will get a URL like ours that you can use in your README file or any Markdown file:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"markdown\"><code><span class=\"line\"><span style=\"color:#E6E8EC\">// Add the following to your README.md to embed Repobeats</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">![</span><span style=\"color:#3AB9BF\">Alt</span><span style=\"color:#E6E8EC\">](</span><span style=\"color:#3AB9BF\">https://repobeats.axiom.co/api/embed/da1c940f0135aece8b9942f518b44dacc39bd9ce.svg</span><span style=\"color:#E6E8EC\"> &#39;</span><span style=\"color:#3AB9BF\">Repobeats analytics image</span><span style=\"color:#E6E8EC\">&#39;</span><span style=\"color:#E6E8EC\">)</span></span></code></pre>\n<h2 id=\"rendering\">Rendering</h2>\n<p>Here is what it looks like for our <a href=\"https://github.com/Open-reSource/openresource.dev\">openresource.dev GitHub repository</a>:</p>\n<p><img src=\"https://repobeats.axiom.co/api/embed/da1c940f0135aece8b9942f518b44dacc39bd9ce.svg\" alt=\"Repobeats card for openresource.dev: pushes, pull requests and issues over the past month, and the top contributors\" title=\"Repobeats analytics image for openresource.dev GitHub repository\"/></p>\n<p>And here is the same kind of data, but on a more active repository like freeCodeCamp:</p>\n<a class=\"entry not-content\" href=\"https://github.com/freeCodeCamp/freeCodeCamp\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/9892522?v=4&amp;s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3><span class=\"owner\">freeCodeCamp/</span><br/>freeCodeCamp</span><span class=\"description\" data-astro-cid-jxjoqtw3>freeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.</span></span></a>\n<p><img src=\"https://repobeats.axiom.co/api/embed/89be0a1a1c8f641c54f9234a7423e7755352c746.svg\" alt=\"Repobeats card for freeCodeCamp: pushes, pull requests and issues over the past month, and the top contributors\" title=\"Repobeats analytics image for freeCodeCamp GitHub repository\"/></p>\n<p>freeCodeCamp is using it in the <a href=\"https://github.com/freeCodeCamp/freeCodeCamp?tab=readme-ov-file#contributing\">“Contributing” section of their README file</a> and it looks great!</p>\n<p>We can see right away that this repository is very active with a lot of contributions, issues, PRs, and commits.</p>",
      "date_published": "2024-04-02T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "GitHub",
        "Markdown",
        "Readme",
        "Tools"
      ]
    },
    {
      "id": "https://openresource.dev/articles/github-marketplace-social-preview-for-your-github-actions/",
      "url": "https://openresource.dev/articles/github-marketplace-social-preview-for-your-github-actions/",
      "title": "GitHub Marketplace: Social Preview for Your GitHub Actions",
      "summary": "Learn how to create and add a social preview image to your GitHub repository to have a better rendering when sharing on social media platforms the link of your GitHub Actions on the GitHub Marketplace.",
      "content_html": "<p class=\"lead\">You are finally ready to share your GitHub Action with the world. You have spent hours working on it, and now it is time to show it off. You open your favorite social media platform, start typing your post, link your GitHub Action on the GitHub Marketplace, click on send, and… your big face is on people’s screen!</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-1.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-1.png\" alt=\"The social preview of my GitHub Action's Marketplace link: my profile picture, large, and nothing about the action.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"458\" height=\"327\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The social preview of my GitHub Action's Marketplace link: my profile picture, large, and nothing about the action.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-1.png\" alt=\"The social preview of my GitHub Action's Marketplace link: my profile picture, large, and nothing about the action.\" width=\"458\" height=\"327\" data-astro-cid-lanmunwp></dialog></div>\n<p>This is what happened to me when I shared the <a href=\"https://github.com/marketplace/actions/update-issue-body\">marketplace link of my GitHub Action named “Update Issue Body”</a>.</p>\n<p>To be fair, the rendering is different and way better if one shares a link to the <a href=\"https://github.com/julien-deramond/update-issue-body\">GitHub Action repository itself</a>.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-2.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-2.png\" alt=\"The social preview of my GitHub Action's repository link, with the project's name, description and stats.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"449\" height=\"318\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The social preview of my GitHub Action's repository link, with the project's name, description and stats.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-2.png\" alt=\"The social preview of my GitHub Action's repository link, with the project's name, description and stats.\" width=\"449\" height=\"318\" data-astro-cid-lanmunwp></dialog></div>\n<h2 id=\"what-can-we-do-about-it\">What Can We Do About It?</h2>\n<p>It is possible to add a social preview image to your GitHub repository. This image will be used when you share the link to your repository on social media platforms. But this image will also be used when you share the link to your GitHub Action on the GitHub Marketplace!</p>\n<p>It is rather easy to do as everything is explained directly in the GitHub documentation <a href=\"https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/customizing-your-repositorys-social-media-preview\">Customizing your repository’s social media preview</a>.</p>\n<p>At the times of writing, images are recommended to be 1280x640px for best display on high-resolution devices.</p>\n<p>While not visible in the documentation itself, GitHub provides in the settings of your repository a template for the social preview image which is pretty handy to get started and to have the safe zones.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-3.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-3.png\" alt=\"Repo card template provided by GitHub with safe zones\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"360\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"Repo card template provided by GitHub with safe zones\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-3.png\" alt=\"Repo card template provided by GitHub with safe zones\" width=\"720\" height=\"360\" data-astro-cid-lanmunwp></dialog></div>\n<p>I am not a designer, so I used the template to create my social preview image which has the following rendering:</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-4.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-4.png\" alt=\"My action's social preview, made from GitHub's repo card template: profile picture, project name, description and username.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"360\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"My action's social preview, made from GitHub's repo card template: profile picture, project name, description and username.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-4.png\" alt=\"My action's social preview, made from GitHub's repo card template: profile picture, project name, description and username.\" width=\"720\" height=\"360\" data-astro-cid-lanmunwp></dialog></div>\n<h2 id=\"how-to-check-if-it-works\">How To Check If It Works?</h2>\n<p>After having uploaded the image to your repository, you can check if it works by using online tools like <a href=\"https://www.opengraph.xyz/\">opengraph.xyz</a>.</p>\n<p>Whether you use the marketplace link or the repository link, you should see the social preview image.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-5.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-5.png\" alt=\"opengraph.xyz previewing my new social image on several social platforms, rendered the same way on each.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"446\" height=\"1272\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"opengraph.xyz previewing my new social image on several social platforms, rendered the same way on each.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/github-marketplace-social-preview-for-your-github-actions-5.png\" alt=\"opengraph.xyz previewing my new social image on several social platforms, rendered the same way on each.\" width=\"446\" height=\"1272\" data-astro-cid-lanmunwp></dialog></div>\n<h2 id=\"find-this-template-on-figma\">Find This Template On Figma</h2>\n<p>Based on this rendering, I have created <a href=\"https://www.figma.com/community/file/1285681647987701740\">a reusable Figma template named “GitHub Actions and Repo Social Previews”</a> that you can use to create your own social preview image.</p>",
      "date_published": "2023-09-15T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "Communication",
        "GitHub",
        "GitHub Actions"
      ]
    },
    {
      "id": "https://openresource.dev/articles/display-your-sponsors-in-your-github-readmes/",
      "url": "https://openresource.dev/articles/display-your-sponsors-in-your-github-readmes/",
      "title": "Display Your Sponsors in Your GitHub READMEs",
      "summary": "Learn how to display the list of your sponsors in your GitHub READMEs thanks to SponsorKit and GitHub Actions.",
      "content_html": "<p class=\"lead\">A simple nice way to reward your sponsors could be to showcase them in the projects you create on GitHub. And what a better place to do that than in your READMEs? This article will show you how to do that easily!</p>\n<p>There are several ways to display your sponsors in your GitHub READMEs, but this article will focus on a single one by using <a href=\"https://github.com/antfu/sponsorkit\">SponsorKit</a> created by <a href=\"https://github.com/antfu\">Anthony Fu</a>.</p>\n<a class=\"entry not-content\" href=\"https://github.com/antfu/sponsorkit\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/167634566?v=4&amp;s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3><span class=\"owner\">antfu/</span><br/>sponsorkit</span><span class=\"description\" data-astro-cid-jxjoqtw3>💖 Toolkit for generating sponsors images 😄</span></span></a>\n<p><strong>SponsorKit</strong> is a toolkit for generating sponsors images that supports GitHub Sponsors, Open Collective, Patreon, and Afdian.</p>\n<p>Here’s how Anthony uses it himself in <a href=\"https://github.com/antfu/unplugin-auto-import#sponsors\">antfu/unplugin-auto-import README</a>.</p>\n<p>Let’s do our own sponsors image showcasing our GitHub sponsors!</p>\n<h2 id=\"prerequisites\">Prerequisites</h2>\n<p>Before starting, you will need to have a GitHub account and have at least one sponsor.</p>\n<p>Then, you will need to create a new GitHub personal access token (classic) with the <code>read:org</code>, and <code>read:user</code> scopes that you can name whatever you want, and keep its value somewhere for the next steps of this tutorial.</p>\n<p>You can find more information about how to create a GitHub token in the <a href=\"https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token\">GitHub documentation</a>.</p>\n<h2 id=\"create-your-repository\">Create Your Repository</h2>\n<p>In order to facilitate the process, we have created for you a template repository that you can use to create your own repository: <a href=\"https://github.com/Open-reSource/sponsorkit-starter\">https://github.com/Open-reSource/sponsorkit-starter</a>.</p>\n<a class=\"entry not-content\" href=\"https://github.com/Open-reSource/sponsorkit-starter\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/129324099?v=4&amp;s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3><span class=\"owner\">Open-reSource/</span><br/>sponsorkit-starter</span><span class=\"description\" data-astro-cid-jxjoqtw3>Starter template for SponsorKit</span></span></a>\n<h3 id=\"from-the-starter-template\">From the Starter Template</h3>\n<p>You can click on the “Use this template” button to create your own repository.</p>\n<p>Then, you will need to fill the form with the name of your repository, a description, and choose if you want to make it public or private. Click on the “Create repository from template” button to create your repository.</p>\n<p>It will launch a GitHub Action that will fail, but don’t worry, we will fix that in the next steps.</p>\n<h3 id=\"from-a-new-repository\">From a New Repository</h3>\n<p>It is also possible to create your repository from scratch, clone it locally, and then running the following command:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"sh\"><code><span class=\"line\"><span style=\"color:#8FE1E6\">npx</span><span style=\"color:#F083A7\"> degit</span><span style=\"color:#F083A7\"> Open-reSource/sponsorkit-starter</span></span></code></pre>\n<h2 id=\"configure-your-repository\">Configure Your Repository</h2>\n<p>Your new repository is now created, and should contain the following files:</p>\n<ul>\n<li><code>.github/workflows/scheduler.yml</code> that runs the SponsorKit action on a schedule every day, for each merge on the main branch, or manually.</li>\n<li><code>.env.example</code> as described in <a href=\"https://github.com/antfu/sponsorkit/#usage\">SponsorKit usage</a>.</li>\n<li><code>build.sh</code> script to generate the sponsors images.</li>\n<li><code>package.json</code> relying on the latest version of SponsorKit and containing the build script.</li>\n<li><code>sponsor.config.ts</code> that contains the configuration for the generation of the sponsors images.</li>\n</ul>\n<h3 id=\"change-default-permissions-of-github_token\">Change Default Permissions of GITHUB_TOKEN</h3>\n<p>First important thing to do is to change the default permissions of the <code>GITHUB_TOKEN</code> that is used by the GitHub Action to commit and push the generated sponsors images.</p>\n<p>It can be changed by going to your repository settings, then to the “Actions” section, and choose “Read and write permissions” for the “Workflow permissions” option.</p>\n<p>You can find more information about this configuration in the <a href=\"https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#configuring-the-default-github_token-permissions\">GitHub documentation</a>.</p>\n<h3 id=\"set-up-the-environment-variable\">Set up the environment variable</h3>\n<p>By looking at <code>.github/workflows/scheduler.yml</code>, we can see that it relies on a <code>${{ secrets.SPONSORS_TOKEN }}</code> environment variable.</p>\n<p>We will need to set it up in the GitHub repository settings with “SPONSORS_TOKEN” as a name, and with the value of the GitHub personal access token that we have created in the prerequisites.</p>\n<p>You can find more information about how to create a new repository secret in the <a href=\"https://docs.github.com/en/actions/how-tos/write-workflows/choose-what-workflows-do/use-secrets#creating-secrets-for-a-repository\">GitHub documentation</a>.</p>\n<h3 id=\"configure-the-github-action\">Configure the GitHub Action</h3>\n<p>Either after having cloned your repository locally, or directly on GitHub, you will need to edit the <code>.github/workflows/scheduler.yml</code> to indicate your GitHub username as a value for “SPONSORKIT_GITHUB_LOGIN”.</p>\n<p>Commit and push your changes.</p>\n<h2 id=\"check-your-generated-images\">Check Your Generated Images</h2>\n<p>This latter change will trigger the GitHub Action that will generate your sponsors images, commit, and push them at the root level of your repository with the message <em>” chore: update sponsors.svg”</em>.</p>\n<p>For example, you can see the generated sponsors images of the <a href=\"https://github.com/julien-deramond/static\">julien-deramond/static</a> repository created from this same template.</p>\n<h2 id=\"optional-generate-the-images-locally\">(Optional) Generate The Images Locally</h2>\n<details><summary>More information</summary><p>It might be useful to know, even if rarely useful, it is also possible to run it locally.</p><p>You will need to install the dependencies by running <code>npm i</code> in your terminal.</p><p>Then, copy <code>.env.example</code> to <code>.env</code> still at the root level of your repository with the following content:</p><pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>; GitHub provider.</span></span>\n<span class=\"line\"><span>; Token requires the `read:user` and `read:org` scopes.</span></span>\n<span class=\"line\"><span>SPONSORKIT_GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxx</span></span>\n<span class=\"line\"><span>SPONSORKIT_GITHUB_LOGIN=username</span></span></code></pre><ul>\n<li><code>SPONSORKIT_GITHUB_TOKEN</code> is the GitHub token you created earlier.</li>\n<li><code>SPONSORKIT_GITHUB_LOGIN</code> is your GitHub username.</li>\n</ul><p>The final step is to run <code>npm run build</code> in your terminal to generate the static files:</p><pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"sh\"><code><span class=\"line\"><span style=\"color:#8FE1E6\">ju</span><span style=\"color:#F083A7\"> ߷</span><span style=\"color:#F083A7\"> ~/j/static</span><span style=\"color:#F083A7\"> ➤</span><span style=\"color:#E6E8EC\"> (main) npm run build                                                                                                                                                          \t(</span><span style=\"color:#8FE1E6\">0.060674</span><span style=\"color:#F083A7\"> hrs</span><span style=\"color:#E6E8EC\">)</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">                                                                                                                                                                                                  \t17:48:16</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">SponsorKit</span><span style=\"color:#F083A7\"> v0.8.3</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Loaded</span><span style=\"color:#F083A7\"> from</span><span style=\"color:#F083A7\"> cache</span><span style=\"color:#F083A7\"> ./.cache.json</span><span style=\"color:#F083A7\">                                                                                                                                                                 \t17:48:16</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Wrote</span><span style=\"color:#F083A7\"> to</span><span style=\"color:#F083A7\"> ./sponsors.json</span><span style=\"color:#F083A7\">                                                                                                                                                                        \t17:48:16</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">ℹ</span><span style=\"color:#F083A7\"> Composing</span><span style=\"color:#F083A7\"> SVG...</span><span style=\"color:#F083A7\">                                                                                                                                                                                \t17:48:16</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Wrote</span><span style=\"color:#F083A7\"> to</span><span style=\"color:#F083A7\"> ./sponsors.svg</span><span style=\"color:#F083A7\">                                                                                                                                                                         \t17:48:16</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Wrote</span><span style=\"color:#F083A7\"> to</span><span style=\"color:#F083A7\"> ./sponsors.png</span><span style=\"color:#F083A7\">                                                                                                                                                                         \t17:48:16</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">                                                                                                                                                                                                  \t17:48:17</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">SponsorKit</span><span style=\"color:#F083A7\"> v0.8.3</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Loaded</span><span style=\"color:#F083A7\"> from</span><span style=\"color:#F083A7\"> cache</span><span style=\"color:#F083A7\"> ./.cache.json</span><span style=\"color:#F083A7\">                                                                                                                                                                 \t17:48:17</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Wrote</span><span style=\"color:#F083A7\"> to</span><span style=\"color:#F083A7\"> ./sponsors.wide.json</span><span style=\"color:#F083A7\">                                                                                                                                                                   \t17:48:17</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">ℹ</span><span style=\"color:#F083A7\"> Composing</span><span style=\"color:#F083A7\"> SVG...</span><span style=\"color:#F083A7\">                                                                                                                                                                                \t17:48:17</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Wrote</span><span style=\"color:#F083A7\"> to</span><span style=\"color:#F083A7\"> ./sponsors.wide.svg</span><span style=\"color:#F083A7\">                                                                                                                                                                    \t17:48:17</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Wrote</span><span style=\"color:#F083A7\"> to</span><span style=\"color:#F083A7\"> ./sponsors.wide.png</span><span style=\"color:#F083A7\">                                                                                                                                                                    \t17:48:17</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">                                                                                                                                                                                                  \t17:48:17</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">SponsorKit</span><span style=\"color:#F083A7\"> v0.8.3</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Loaded</span><span style=\"color:#F083A7\"> from</span><span style=\"color:#F083A7\"> cache</span><span style=\"color:#F083A7\"> ./.cache.json</span><span style=\"color:#F083A7\">                                                                                                                                                                 \t17:48:17</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Wrote</span><span style=\"color:#F083A7\"> to</span><span style=\"color:#F083A7\"> ./sponsors.part1.json</span><span style=\"color:#F083A7\">                                                                                                                                                                  \t17:48:17</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">ℹ</span><span style=\"color:#F083A7\"> Composing</span><span style=\"color:#F083A7\"> SVG...</span><span style=\"color:#F083A7\">                                                                                                                                                                                \t17:48:17</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Wrote</span><span style=\"color:#F083A7\"> to</span><span style=\"color:#F083A7\"> ./sponsors.part1.svg</span><span style=\"color:#F083A7\">                                                                                                                                                                   \t17:48:17</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Wrote</span><span style=\"color:#F083A7\"> to</span><span style=\"color:#F083A7\"> ./sponsors.part1.png</span><span style=\"color:#F083A7\">                                                                                                                                                                   \t17:48:18</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">                                                                                                                                                                                                  \t17:48:18</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">SponsorKit</span><span style=\"color:#F083A7\"> v0.8.3</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Loaded</span><span style=\"color:#F083A7\"> from</span><span style=\"color:#F083A7\"> cache</span><span style=\"color:#F083A7\"> ./.cache.json</span><span style=\"color:#F083A7\">                                                                                                                                                                 \t17:48:18</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Wrote</span><span style=\"color:#F083A7\"> to</span><span style=\"color:#F083A7\"> ./sponsors.part2.json</span><span style=\"color:#F083A7\">                                                                                                                                                                  \t17:48:18</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">ℹ</span><span style=\"color:#F083A7\"> Composing</span><span style=\"color:#F083A7\"> SVG...</span><span style=\"color:#F083A7\">                                                                                                                                                                                \t17:48:18</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Wrote</span><span style=\"color:#F083A7\"> to</span><span style=\"color:#F083A7\"> ./sponsors.part2.svg</span><span style=\"color:#F083A7\">                                                                                                                                                                   \t17:48:18</span></span>\n<span class=\"line\"><span style=\"color:#8FE1E6\">✔</span><span style=\"color:#F083A7\"> Wrote</span><span style=\"color:#F083A7\"> to</span><span style=\"color:#F083A7\"> ./sponsors.part2.png</span></span></code></pre><p>All the images are now generated at the root level of your repository. You can check them out in your file explorer.</p><p><strong>Warning</strong>: Once it’s done, please don’t forget to remove at some point your GitHub token from the <code>.env</code> file for security reasons. You won’t probably never re-run it from your local machine.</p></details>\n<h2 id=\"use-the-generated-images-in-your-readmes\">Use the Generated Images in Your READMEs</h2>\n<p>Now that the GitHub Action has run, you can use the generated images in your READMEs.</p>\n<p>For example, you can use the <code>sponsors.svg</code> image in your <code>README.md</code> file by adding the following code. Don’t forget to replace <code>username</code> by your GitHub username in the link’s <code>href</code>, link’s <code>aria-label</code>, and image’s <code>src</code> attributes.</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"html\"><code><span class=\"line\"><span style=\"color:#E6E8EC\">&lt;</span><span style=\"color:#3AB9BF\">p</span><span style=\"color:#FB8D8C\"> align</span><span style=\"color:#E6E8EC\">=</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#F083A7\">center</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#E6E8EC\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t&lt;</span><span style=\"color:#3AB9BF\">a</span><span style=\"color:#8FE1E6\"> href</span><span style=\"color:#E6E8EC\">=</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#F083A7\">https://github.com/sponsors/username/</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#8FE1E6\"> aria-label</span><span style=\"color:#E6E8EC\">=</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#F083A7\">Go to username&#39;s sponsors page</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#E6E8EC\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t\t&lt;</span><span style=\"color:#3AB9BF\">img</span><span style=\"color:#8FE1E6\"> src</span><span style=\"color:#E6E8EC\">=</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#F083A7\">https://cdn.jsdelivr.net/gh/username/static/sponsors.svg</span><span style=\"color:#E6E8EC\">&quot;</span><span style=\"color:#E6E8EC\"> /&gt;</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">\t&lt;/</span><span style=\"color:#3AB9BF\">a</span><span style=\"color:#E6E8EC\">&gt;</span></span>\n<span class=\"line\"><span style=\"color:#E6E8EC\">&lt;/</span><span style=\"color:#3AB9BF\">p</span><span style=\"color:#E6E8EC\">&gt;</span></span></code></pre>\n<p><strong>Warning</strong>: GitHub can take a while to render the image in your README. If you don’t see it, wait and refresh the page. On my side, it took around 10 minutes to be displayed. As long as the <code>https://cdn.jsdelivr.net/gh/username/static/sponsors.svg</code> URL is showing the image, don’t worry, it will be displayed in your README soon.</p>\n<h2 id=\"final-result\">Final Result</h2>\n<p>You can check my own personal sponsors list generated by following this article:</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://cdn.jsdelivr.net/gh/julien-deramond/static/sponsors.svg\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://cdn.jsdelivr.net/gh/julien-deramond/static/sponsors.svg\" alt=\"Julien Déramond sponsors list\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"272\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"Julien Déramond sponsors list\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://cdn.jsdelivr.net/gh/julien-deramond/static/sponsors.svg\" alt=\"Julien Déramond sponsors list\" width=\"720\" height=\"272\" data-astro-cid-lanmunwp></dialog></div>\n<p>And find it integrated in one of my projects: <a href=\"https://github.com/julien-deramond/update-issue-body#sponsors\">https://github.com/julien-deramond/update-issue-body#sponsors</a>.</p>",
      "date_published": "2023-05-18T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "GitHub",
        "Sponsors",
        "Tutorial"
      ]
    },
    {
      "id": "https://openresource.dev/articles/can-i-take-this-issue/",
      "url": "https://openresource.dev/articles/can-i-take-this-issue/",
      "title": "Can I Take This Issue?",
      "summary": "Learn about the frustration caused by issue assignments in open-source software development and how to tackle it. Get insights here.",
      "content_html": "<p class=\"lead\">Open-source software development is a collaborative effort that relies on volunteers to contribute to the project. Contributors have different skill levels and come from various backgrounds. As such, project maintainers make sure that the contributions received are of high quality and meet the project’s goals. One way maintainers do this is by providing clear guidelines on how contributors can submit their work. Unfortunately, contributors don’t always take the time to read these guidelines, and maintainers don’t always assign issues, which can lead to confusion and frustration on both sides.</p>\n<h2 id=\"so-can-i-take-it-or-not\">So Can I Take It or Not?</h2>\n<div class=\"chat chat-start\" data-astro-cid-r7wgiqdd><div class=\"chat-header\" data-astro-cid-r7wgiqdd>Contributor<span class=\"d-visually-hidden\" data-astro-cid-r7wgiqdd>says</span></div><div class=\"chat-bubble\" data-astro-cid-r7wgiqdd><p>Hey! Can I take this issue?</p></div></div>\n<div class=\"chat chat-end\" data-astro-cid-r7wgiqdd><div class=\"chat-header\" data-astro-cid-r7wgiqdd>Maintainer<span class=\"d-visually-hidden\" data-astro-cid-r7wgiqdd>says</span></div><div class=\"chat-bubble\" data-astro-cid-r7wgiqdd><p>Hello! As mentioned in <span style=\"text-decoration: underline\">our contributing guidelines</span>, we do not assign\nissues in this repository. However, if you’d like to contribute a solution, feel free to create a PR directly. Thank\nyou for your interest!</p></div></div>\n<div class=\"chat chat-start\" data-astro-cid-r7wgiqdd><div class=\"chat-header\" data-astro-cid-r7wgiqdd>Contributor<span class=\"d-visually-hidden\" data-astro-cid-r7wgiqdd>says</span></div><div class=\"chat-bubble\" data-astro-cid-r7wgiqdd><p>OK thanks!</p></div></div>\n<p>This is a common scenario in open-source projects. A contributor sees an issue that they think they can solve, so they ask if they can take it.</p>\n<div class=\"chat chat-end chat-thinking\" data-astro-cid-r7wgiqdd><div class=\"chat-header\" data-astro-cid-r7wgiqdd>Maintainer<span class=\"d-visually-hidden\" data-astro-cid-r7wgiqdd>thinks</span></div><div class=\"chat-bubble\" data-astro-cid-r7wgiqdd><p>Seriously, again… What do I usually answer? Hmmm…</p></div></div>\n<p>If you are the maintainer of this open-source project, you start by receiving a notification. You then go to the issue and take the time to respond to the contributor something you may have already said ten times this week. You then go back to your work, and receive another notification from the same contributor saying basically “OK thanks!”.</p>\n<div class=\"chat chat-start chat-thinking\" data-astro-cid-r7wgiqdd><div class=\"chat-header\" data-astro-cid-r7wgiqdd>Contributor<span class=\"d-visually-hidden\" data-astro-cid-r7wgiqdd>thinks</span></div><div class=\"chat-bubble\" data-astro-cid-r7wgiqdd><p>Seriously? I have already checked the issue, I have the solution!!! They don’t trust me. They think I’m not good\nenough, they don’t deserve my contribution…</p></div></div>\n<p>If you are the contributor, you may feel frustrated. You may have spent time looking for an issue to work on, and you may have even started working on it. You then ask if you can take it, and the maintainer responds by saying that they don’t assign issues. You then feel discouraged and decide not to contribute to the project.</p>\n\n<p><strong style=\"color: var(--color-primary); font-size: 1.25rem; line-height: 1.75rem;\">This is a frustrating experience for both the contributor and the maintainer</strong>.</p>\n<p>The contributor is left wondering if they can actually work on the issue, and the maintainer is left wondering why the contributor didn’t read the contributing guidelines.</p>\n<h2 id=\"why-do-some-maintainers-assign-issues\">Why Do Some Maintainers Assign Issues?</h2>\n<p>Maintaining an open-source project is a challenging task that involves multiple responsibilities. One of them is managing issues reported by contributors or users. Assigning issues to specific maintainers or contributors is a common practice that can help ensure that problems are addressed in a timely and efficient manner and that contributions align with the project’s vision and goals. However, not all maintainers assign issues, or they may only assign a small number of them.</p>\n<h3 id=\"efficiency\">Efficiency</h3>\n<p>Assigning issues to specific individuals helps ensure that they are addressed promptly and efficiently, reducing the likelihood of issues being overlooked or forgotten. It allows maintainers to manage issues more efficiently, ensuring they are resolved in a timely and effective manner. However, the assignee can still benefit from the feedback of the community and maintainers, and this approach is particularly useful for larger projects that receive many issues.</p>\n<h3 id=\"accountability-and-responsibility\">Accountability and Responsibility</h3>\n<p>Assigning issues can help to clarify the responsibilities of different contributors and maintainers. It’s clear who is responsible for resolving an issue when it’s assigned to a specific person. This can reduce confusion and ensure that issues are addressed by the right people. In larger projects, where multiple contributors and maintainers may be working simultaneously.</p>\n<p>Assigning issues can also create a clear sense of accountability and responsibility. When an issue is assigned to a specific person, they become responsible for resolving it. This accountability can motivate contributors and maintainers to take ownership of the issue and work towards a solution. When contributors know that they are responsible for resolving an issue, they are more likely to focus their efforts on finding a solution. This sense of ownership can also lead to a more engaged and invested community.</p>\n<h3 id=\"encouraging-contributions\">Encouraging Contributions</h3>\n<p>Assigning issues to specific contributors can foster community involvement and collaboration. Assignees have a clear understanding of what needs to be done, leading to increased contributions and a more active community. Additionally, assigning issues can encourage collaboration between contributors and maintainers, leading to more efficient issue resolution and a stronger sense of community.</p>\n<p>To address unassigned contributions, both contributors and maintainers need to work together.</p>\n<p>Contributors can help by taking the time to read the project’s contribution guidelines carefully. They should also review the issue tracker and try to find issues that align with their skills and interests. If an issue is not assigned, contributors can reach out to maintainers or community managers for guidance.</p>\n<p>Maintainers can also take steps to address unassigned contributions. One way is to review the issue tracker regularly and assign issues promptly. They can also update the contribution guidelines and make them more visible to ensure that contributors are aware of them. Maintainers can also provide feedback on contributions, highlighting areas for improvement and encouraging contributors to continue their work.</p>\n<h3 id=\"better-resource-management\">Better Resource Management</h3>\n<p>Assigning issues can also help to manage resources more effectively.</p>\n<p>By assigning issues to specific contributors or maintainers, the workload can be distributed more evenly. It also helps prevent duplicated work, as contributors can see what others are working on and avoid duplicating their efforts.</p>\n<p>Assigning issues can also help maintainers to manage their workload. By assigning issues to specific people, maintainers can ensure that they are not overwhelmed with too many tasks at once.</p>\n<p>This approach can help to prevent burnout and ensure that contributors and maintainers are working on issues that are within their skill level and expertise. It can ensure that maintainers’ time and energy are focused on the issues that matter most.</p>\n<h3 id=\"avoiding-confusion\">Avoiding Confusion</h3>\n<p>Assigning issues can also help to avoid confusion. When multiple people are working on the same issue, it can be difficult to know who is responsible for what. By assigning issues to specific people, maintainers can ensure that everyone knows what they are responsible for and what their role is in addressing the issue.</p>\n<h2 id=\"why-do-some-maintainers-not-assign-issues\">Why Do Some Maintainers Not Assign Issues?</h2>\n<p>Despite the benefits of assigning issues, there are also some challenges that maintainers may face. So there are some maintainers who choose not to assign issues, quite a lot in fact. This lack of assignment can result in contributors not knowing what to work on or feeling discouraged about contributing to the project.</p>\n<h3 id=\"limited-resources\">Limited Resources</h3>\n<p>Maintaining an open-source project can be a daunting task, and the responsibility is often shouldered by a handful of maintainers. These maintainers are responsible for reviewing contributions, triaging issues, and coordinating with contributors to ensure the project’s growth and success. However, due to limited resources, some maintainers may not be able to assign issues effectively, which can lead to frustration among contributors and a decline in the project’s growth.</p>\n<p>Maintaining an open-source project requires a significant amount of time and effort, and it can be a voluntary and unpaid job for many maintainers. As such, they may not have the financial resources or personnel to manage every issue that is reported.</p>\n<p>Assigning an issue without proper analysis and discussion is inadequate and can impede its development. This is especially true for issues coming from the community, as they may lack sufficient details. Prioritizing, analyzing, and discussing the issue is necessary before assigning it to a maintainer or contributor for resolution. Assigning issues to specific people requires time and effort, and some maintainers may prefer to focus their attention on other aspects of the project, such as code review or documentation. Furthermore, some maintainers may be juggling multiple projects or other commitments in their personal and professional lives, which can limit their ability to assign issues.</p>\n<p>They are often already too busy reviewing contributions. Open-source projects are often community-driven, and they can receive a large number of contributions, especially when they gain traction. Each contribution requires review, testing, and integration, which can be time-consuming, especially for maintainers who have other responsibilities. In such cases, maintaining the project can become a daunting task, and maintainers may be unable to keep up with the influx of contributions, leading to a backlog of unassigned issues and sometimes even unassigned pull requests.</p>\n<p>The issue tracker can become overwhelming, making it difficult to assign issues to the right people. The issue tracker serves as a central hub for the project’s issues, feature requests, and pull requests. As the project grows, the number of issues and pull requests can quickly pile up, leading to confusion on the part of contributors. Without proper triaging and assignment, contributors may not know what to work on or feel discouraged about contributing to the project, resulting in a decline in contributions.</p>\n<h3 id=\"large-communities\">Large Communities</h3>\n<p>As the community expands or is already large, maintainers may struggle to keep track of all its members and their capabilities. In such cases, assigning issues can become a daunting task, as maintainers may be uncertain of the skill level and commitment of potential contributors. Junior developers and new open source members may be attracted to issues in already popular projects, seeking mentorship and opportunities to contribute, but this can overwhelm maintainers who cannot mentor everyone or have limited resources for reviewing contributions.</p>\n<p>To assign issues appropriately, maintainers may need to review past contributions, evaluate code quality, and reach out to potential contributors to discuss their interest in the project. However, this can be a time-consuming process, leading some maintainers to avoid assigning issues altogether. This can create a backlog of issues that go unaddressed, causing frustration among contributors.</p>\n<p>And this approach can backfire, as it can create a backlog of issues that are not being addressed, which can cause frustration among contributors. In such cases, establish clear guidelines for issue assignment and ensure that all members of the community are aware of them.</p>\n<h3 id=\"collaborative-approach\">Collaborative Approach</h3>\n<p>Some maintainers believe that assigning issues can create silos and discourage collaboration. They may prefer to have an open forum where anyone can contribute to resolving issues. This approach allows the community to work together and share knowledge and expertise. They encourage contributors to take ownership of the project and work together to resolve issues, rather than relying on a single maintainer to manage all aspects of the project.</p>\n<p>While this approach can be effective, it can also result in a lack of direction and oversight. Without clear guidance or leadership, contributors may not know what to work on or how to approach a particular issue.</p>\n<p>To address this, maintainers can provide clear documentation on the project goals and how to get involved. Additionally, they can establish communication channels for contributors to ask questions or provide feedback, or even encourage contributors to work in pairs or small groups to resolve issues. Another potential solution is to use a rotating ownership model, where issues are assigned to a specific contributor for a set period of time, after which ownership of the issue rotates to another contributor. This approach allows for individual ownership of issues while still promoting collaboration and knowledge-sharing.</p>\n<p>By doing so, maintainers can foster a collaborative environment while still maintaining some level of oversight and direction.</p>\n<h3 id=\"avoiding-favoritism\">Avoiding Favoritism</h3>\n<p>Assigning issues can also lead to accusations of favoritism or bias. Some maintainers may choose not to assign issues to avoid any perception of preferential treatment. By allowing anyone to work on any issue, maintainers can ensure that everyone has an equal opportunity to contribute. This approach can help to create a more inclusive and welcoming community, where all contributors are valued and respected.</p>\n<p>However, this approach can also result in confusion and duplication of effort. If multiple contributors are working on the same issue, it can lead to wasted time and resources.</p>\n<p>One way to ensure that everyone has a fair opportunity to contribute to a project is through establishing clear guidelines and protocols for contribution. For instance, the project can have a clearly defined process for claiming issues, stating who is responsible for which tasks, and how contributors can go about resolving issues. This approach allows contributors to work together in a coordinated fashion and avoid duplication of effort. In some cases, it may even foster a sense of friendly competition amongst contributors, which can help to drive innovation and progress.</p>\n<p>They can also provide feedback on contributions to ensure that everyone is working towards the same goal, thus minimizing duplication of effort and confusion.</p>\n<h3 id=\"trust-community\">Trust Community</h3>\n<p>Another reason why some maintainers do not assign issues is that they trust the community to self-organize and take ownership of issues without assigning them to specific individuals. This approach is based on the belief that a highly engaged and motivated community will work together to resolve issues and prioritize tasks. It can be an effective approach in projects with a large and active community where multiple contributors can work on the same issue simultaneously.</p>\n<p>When maintainers trust the community to self-organize, they can focus on other aspects of the project such as developing new features, maintaining documentation, or mentoring new contributors. This approach can also be useful in situations where maintainers have limited resources or are unable to keep up with the volume of incoming issues. By allowing the community to take ownership of the project, maintainers can create a sense of ownership and belonging within the community, leading to increased participation and collaboration.</p>\n<p>However, relying solely on the community to self-organize can also have its drawbacks. Without clear guidance or leadership, contributors may not know how to prioritize tasks or resolve issues effectively. Sometimes, the issues are not yet read by the maintainers and contributors start the development of something useless which is not what the maintainers want. This can result in duplication of effort, wasted time and resources, and may lead to frustration and disengagement among contributors.</p>\n<p>To address these issues, maintainers can establish clear guidelines on how to claim an issue and work on it. They can also provide feedback on contributions to ensure that everyone is working towards the same goal. Additionally, maintaining open communication channels for contributors to ask questions or provide feedback can help foster a collaborative environment while still maintaining some level of oversight and direction.</p>\n<h3 id=\"lack-of-familiarity\">Lack of Familiarity</h3>\n<p>We may tend to forget it but not all the maintainers know everything about open source so some maintainers may “choose” not to assign issues simply because they are not familiar with the process. Assigning issues can be a complex task, especially in large projects with many contributors. If a maintainer is not comfortable with the process, they may choose to avoid it altogether. Additionally, some maintainers may be new to the project and may not yet have a good understanding of the various roles and responsibilities. This can make it difficult to assign issues to the appropriate parties.</p>\n<p>In this case, this article may be a good starting point 🙂</p>\n<h2 id=\"hybrid-approach\">Hybrid Approach</h2>\n<p>An open-source project can be maintained by a core team working full-time, often linked to a company. Then, issues assignments may be handled differently than in other open-source projects. Indeed, they can rely on a specific agenda and deadlines, so they may assign issues to ensure accountability, clear ownership, prioritization, expertise, and consistency. At the same time, the core team may also allow external contributors to contribute to the project for diverse perspectives, community building, increased productivity, and learning opportunities. In that case, they could not assign issues to external contributors. Here comes our hybrid approach.</p>\n<p>As an external contributor, you won’t probably be assigned to an issue for several reasons:</p>\n<ul>\n<li>The issue must be tackled soon and they can’t rely on an outsider to deliver a specific task with a deadline.</li>\n<li>The issue requires extra internal information the contributor can’t have access to or internal discussions that happened or will happen and are not tracked, or won’t be tracked in the repository.</li>\n</ul>\n<p>However, it might happen, depending on their contributing guidelines, for unprioritized issues that don’t have any deadline yet. Most repositories use a dedicated label in this case to let know outsiders that they can help and contribute. And of course, they will probably be happy to review code not related to already planned issues or fixes.</p>\n<p>By allowing external contributions to the project, the core team might benefit from:</p>\n<ul>\n<li>A wide range of new perspectives and ideas.</li>\n<li>Building a community around the project.</li>\n<li>Increasing productivity by leveraging the contributions of others.</li>\n<li>Recruiting members of the community.</li>\n<li>Learning from the contributions of others and improving their own skills and knowledge.</li>\n</ul>\n<h2 id=\"how-to-address-the-issue-of-not-assigning-issues\">How to Address the Issue of Not Assigning Issues</h2>\n<p>Not assigning issues is a choice made by the maintainers based on several criteria as seen in the previous sections.</p>\n<h3 id=\"strong-workflow\">Strong Workflow</h3>\n<p>To counter-balance the fact that issues are not assigned, projects often rely on a strong issues workflow with a powerful system of labeling and triage to help identify the complexity of the tasks, the status of the analysis, whether the issue is ready to develop or not, the target versions, the scope, etc. so that the community can be autonomous, but also to reduce the noise for the maintainers who have most of the time really limited resources.</p>\n<p>This full backlog can be accompanied by a schema representing the whole workflow of states of issues and sometimes even pull requests, the actors, etc. It can be linked to a roadmap.</p>\n<p>To make the most of their limited resources, maintainers can set up automatic triage systems that categorize and prioritize issues based on their severity or complexity so that the community can be autonomous and evaluate where they could be helpful depending on their level and expertise. High-priority or high-complexity issues can be tackled by experienced contributors or reserved for the core team while low-priority or low-complexity might be left for the new contributors to help them gain experience.</p>\n<p>Additionally, maintainers can reach out to the community to encourage contributions and provide guidance on how to best help with the project so that the whole process runs smoothly. By doing so, maintainers can ensure that they are making the most of their limited resources, while also making it easier for contributors to get involved.</p>\n<p>Labeling is very powerful as it can filter the backlog by elements but also be used for automation in projects.</p>\n<p>Everything can start from the creation of these issues with the issues templates to guide contributors in providing the necessary information when they create an issue. This can include a checklist of requirements that need to be met before an issue can be treated, such as providing a clear description of the problem, steps to reproduce, any relevant logs or errors messages, or motivation if this is a new feature.</p>\n<ul>\n<li><a href=\"https://docs.gitlab.com/ee/user/project/description_templates.html\">Description templates on GitLab</a></li>\n<li><a href=\"https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository\">Configuring issue templates on GitHub</a></li>\n</ul>\n<blockquote>\n<p>[!TIP]\nWhen you don’t assign issues in your repository, it can be reminded at the end of the issues!</p>\n</blockquote>\n<p>As of September 2026, GitHub doesn’t provide any options to add some Markdown content at the end of the issues when using issue templates: the <code>markdown</code> elements of an issue form are shown to the author but not submitted. However, you can use GitHub Actions to do that. Here is an example of a GitHub Action that adds a message for newly created issues:</p>\n<a class=\"entry not-content\" href=\"https://github.com/Open-reSource/labs-append-markdown-to-issues\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/129324099?v=4&amp;s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3><span class=\"owner\">Open-reSource/</span><br/>labs-append-markdown-to-issues</span><span class=\"description\" data-astro-cid-jxjoqtw3>[Labs] GitHub Action that append Markdown to issues</span></span></a>\n<p>An infinite way of managing labels is possible. Let’s imagine, for example, a <span class=\"d-badge d-badge--neutral\">to analyze</span> label that can be picked up only by a core team member. When this core team member analyzed the issue and provided expectations, clarity, and guidance, the label could be transformed into an <span class=\"d-badge d-badge--neutral\">analyzed</span> label, and a new <span class=\"d-badge d-badge--neutral\">ready for dev</span> label could be applied combined to <span class=\"d-badge d-badge--neutral\">high priority</span> and <span class=\"d-badge d-badge--neutral\">low complexity</span> labels, and a <span class=\"d-badge d-badge--neutral\">version 12</span> label, <span class=\"d-badge d-badge--neutral\">bug</span> or <span class=\"d-badge d-badge--neutral\">feature</span>, <span class=\"d-badge d-badge--neutral\">core team</span> if it is reserved for the core team, or <span class=\"d-badge d-badge--neutral\">pr welcome</span> when it is OK for external contributors to work on it. When doing that, contributors can start to help or not, filter the backlog by labels, and the core team can focus on the most important issues. If the workflow is automated, the issue can go to one or another project, be in a roadmap, etc. This is just an example, but you can imagine how powerful it can be.</p>\n<h3 id=\"communicate-clearly\">Communicate Clearly</h3>\n<p>By establishing clear communication channels, maintainers can provide guidance to contributors and answer any questions they may have about the assignment process and issues workflow. This can also help build trust and foster a sense of community among contributors, which can lead to greater collaboration and more successful outcomes.</p>\n<p>By taking the time to establish clear guidelines and protocols for issues assignment and maintaining open communication with contributors, maintainers can help ensure that each issue is addressed by the most qualified contributor, leading to more successful outcomes for the project as a whole.</p>\n<p>Whether maintainers put in place a simple or advanced workflow, it must be clearly explained somewhere. Depending on the amount of information, it can be directly in the Contributing Guidelines or in a Wiki, documentation, etc. linked from the Contributing Guidelines.</p>\n\n<p><strong style=\"color: var(--color-primary); font-size: 1.25rem; line-height: 1.75rem;\">If issues are assigned, make sure that it’s clearly explained in the Contributing Guidelines</strong>.</p>\n\n<p><strong style=\"color: var(--color-primary); font-size: 1.25rem; line-height: 1.75rem;\">If issues are not assigned, make sure that it’s clearly explained in the Contributing Guidelines</strong>.</p>\n<h4 id=\"the-importance-of-contribution-guidelines\">The Importance of Contribution Guidelines</h4>\n<p>Yes, it is important for open-source projects to have Contributing Guidelines to provide critical information about the project, including its goals, coding standards, how to submit changes, how to ask for help, and how to get involved in the community.</p>\n<p>This is also the place where are explained how contributors can report issues and how maintainers will manage them. <strong>The guidelines should include information on whether issues will be assigned or left unassigned, and why</strong>. This will help to set expectations for both contributors and maintainers and ensure that everyone is on the same page.</p>\n<p>If an open-source project is maintained by a core team working for a company, the contribution guidelines should make it clear that issues will be managed by the core team and may or may not be assigned to individual team members. The guidelines should also explain the reasons behind this approach, such as the need to ensure that issues are addressed in a timely and efficient manner, and the fact that the core team has the expertise and resources to manage the project effectively.</p>\n<p>If an open-source project is maintained by a community of volunteers, the contribution guidelines should explain how issues will be managed and whether they will be assigned or left unassigned. The guidelines should also provide guidance on how contributors can help to manage the issue tracker, such as by reviewing and triaging issues, and how they can get involved in the project’s decision-making process.</p>\n<p>Regardless of the approach taken by an open-source project, it’s important to have clear and transparent contribution guidelines that set expectations for both contributors and maintainers. This will help to ensure that the project is sustainable and that issues are addressed in a timely and efficient manner.\nOn top of explaining what is the process, it is also interesting to explain why this choice has been made by the maintainers. It will help contributors who will read the contributing guidelines, but can also be useful to remind this rule for those who don’t read the contributing guidelines. It happens sometimes, doesn’t it? ;)</p>\n<h4 id=\"often-contributors-dont-read-the-contributing-guidelines\">Often, contributors don’t read the contributing guidelines</h4>\n<p>First of all, contributors may not even know their existence. Always remind that each day, there are newcomers in the open source world who don’t know how it works. But let’s be honest, apart if the Contributing Guidelines are not at the right place, contributors don’t always take the time to read them because they may be in a hurry to start working on the project, or because they assume that their previous experience will suffice.</p>\n<p>So the frustration of maintainers can be understood rather easily, especially if they spent time writing down a thorough explanation of why the repository doesn’t assign issues. Reminding days after days for years that the repository doesn’t assign issues feels like repeating over and over the same thing. But always remind that you are not talking to the same person who has a different background regarding OSS and probably does not have the same expertise as you in the field.</p>\n<p>Streamers, for example, use pre-defined messages, videos, or FAQs in order not to repeat the same information to the newcomers (who almost always ask the same things based on the streamer’s point of view) so that they are not bothered when they are streaming, and the viewers can still have the information. Having tools answering for you, either semi-automatic or automatic, will help not become angry at contributors after repeating the same thing over and over.</p>\n<p>In a nutshell:</p>\n<ul>\n<li><strong>Make the Contributing Guidelines clear and easy to find.</strong> Ensure that they are prominently displayed on the project’s website, README file, in the documentation, in the issues templates, etc. Make sure they are easy to read and understand, with clear instructions on how to contribute and how the issues are handled in the global workflow.</li>\n<li><strong>Communicate clearly with contributors.</strong> Even if it is mentioned everywhere, always remind nicely this information to the contributors who make mistakes. Provide clarity and guidance.</li>\n<li><strong>Be consistent.</strong> Ensure that the rules for assigning issues are consistent across the project and that all maintainers are aware of them. This can help prevent confusion and ensure that all contributors are treated fairly. Having a unique reference stored in only one place is really handy because maintainers will be able to link this reference instead of reinterpreting the content every time, and maybe not being consistent. Plus, it’s always true even if the reference changes.</li>\n<li><strong>Consider revisiting the guidelines.</strong> If you find that many contributors are not following the guidelines, it may be worth revising them to be clearer or to better reflect the needs of the project. However, be sure to communicate any changes clearly to existing contributors and provide guidance on how to adjust their contributions accordingly.</li>\n</ul>\n<p>Overall, the key is to be patient, clear, and helpful in your interactions with contributors. By doing so, you can create a welcoming and productive community around your open-source project</p>\n<h3 id=\"manual-semi-automatic-and-automatic-tools\">Manual, Semi-automatic, and Automatic Tools</h3>\n<p>Overall, by using a combination of manual, semi-automatic, and automatic tools, maintainers can help to manage the influx of questions from contributors who are unsure about taking up an issue. This can help to ensure that contributors are able to contribute effectively and that maintainers can focus on other aspects of the project.</p>\n<p>There are several manual and automatic tools that maintainers can use to help handle these questions and politely refuse them by mentioning the contribution guidelines.</p>\n<p><strong>Direct communication</strong> is not really a tool, but this is often the way it is handled by maintainers. They can engage with contributors who are unsure about taking up an issue, write down a specific <strong>personalized message</strong>, help clarify any confusion and ensure that contributors feel supported to contribute in the right way, and even provide alternative issues or areas of the project where the contributor can help. But it takes a huge amount of time, especially in a big community, and the content can be inconsistent.</p>\n<p>In most of the Git source code platforms, it is possible to set up <strong>saved replies</strong>:</p>\n<ul>\n<li><a href=\"https://docs.gitlab.com/ee/user/profile/comment_templates.html\">Comment templates on GitLab</a></li>\n<li><a href=\"https://docs.github.com/en/get-started/writing-on-github/working-with-saved-replies/using-saved-replies\">Using saved replies on GitHub</a></li>\n</ul>\n<p>It is only a semi-automatic tool but it can help save a lot of time by not repeating over and over the same thing. Maintainers will lose the personalized side but will gain consistency with a clear and precise answer accompanied by links pointing to unique resources.</p>\n<p>If you are maintaining OSS projects or communities on different platforms, you may opt for <strong>decentralized messages and actions</strong> stored in your own environment for transversal usage. Tools like <a href=\"https://www.alfredapp.com/\">Alfred</a> on macOS could be used in this spirit.</p>\n<p>Writing this article was the occasion to try creating a <strong>semi-automation tool based on labels</strong>. Maintainer can add a <span class=\"d-badge d-badge--neutral\">we don’t assign issues</span> label to an issue right after a comment asking to be assigned. This label will trigger a GitHub action that will write a personalized comment explaining that the repo is not handled that way, and then remove this label automatically. We could even hide the original contributor’s comment in the process.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://user-images.githubusercontent.com/17381666/236413271-12b7b2f2-12b1-4498-99d0-19db8b4b97d8.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://user-images.githubusercontent.com/17381666/236413271-12b7b2f2-12b1-4498-99d0-19db8b4b97d8.png\" alt=\"A maintainer adds the “we don’t assign issues” label; the github-actions bot posts the policy and removes the label.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"274\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"A maintainer adds the “we don’t assign issues” label; the github-actions bot posts the policy and removes the label.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://user-images.githubusercontent.com/17381666/236413271-12b7b2f2-12b1-4498-99d0-19db8b4b97d8.png\" alt=\"A maintainer adds the “we don’t assign issues” label; the github-actions bot posts the policy and removes the label.\" width=\"720\" height=\"274\" data-astro-cid-lanmunwp></dialog></div>\n<p>The source code of this experiment is available on GitHub via the card below.</p>\n<a class=\"entry not-content\" href=\"https://github.com/Open-reSource/labs-we-don-t-assign-issues\" data-astro-cid-jxjoqtw3><img src=\"https://avatars.githubusercontent.com/u/129324099?v=4&amp;s=96\" alt=\"\" width=\"48\" height=\"48\" loading=\"lazy\" data-astro-cid-jxjoqtw3><span class=\"text\" data-astro-cid-jxjoqtw3><span class=\"name\" data-astro-cid-jxjoqtw3><span class=\"owner\">Open-reSource/</span><br/>labs-we-don-t-assign-issues</span><span class=\"description\" data-astro-cid-jxjoqtw3>[Labs] &quot;we don't assign issues&quot; label that writes a comment and is then auto-deleted</span></span></a>\n<p>Unfortunately, if there are intermediate comments before maintainers have the time to use this label, it won’t work. And it stays semi-automatic.</p>\n<p>This was a nice experiment, but <strong>can we go further with full automation?</strong> Actions can already be triggered when a comment is created or updated, it would only be a matter of time to create a bot that would be able to answer automatically to the contributor.</p>\n<p>We keep seeing new AI tools popping up every day in our feeds. They are pretty powerful and help automation. But so far, we haven’t had the occasion to find or test such tools for this specific use case. If you have any suggestions, or links, you can <a href=\"https://github.com/Open-reSource/openresource.dev/issues/new/choose\">create an issue</a> so that we can test them and improve this article. Or come talk about it on <a href=\"https://discord.gg/fpUDwEMGwE\">our Discord</a>.</p>\n<p>On the contributor’s side, <a href=\"https://openresource.dev/guide/contributing/finding-open-source-projects/\">Finding a Project to Contribute To</a> covers where to find an issue and how to start on it without wasting an afternoon, and <a href=\"https://openresource.dev/guide/getting-started/open-source-etiquette/#say-how-before-you-spend-a-weekend-on-it\">Open Source Etiquette</a> the comment to write instead of “Can I take this issue?”.</p>",
      "date_published": "2023-05-15T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "Community",
        "Contribution"
      ]
    },
    {
      "id": "https://openresource.dev/articles/how-to-create-a-code-of-conduct-for-an-open-source-project/",
      "url": "https://openresource.dev/articles/how-to-create-a-code-of-conduct-for-an-open-source-project/",
      "title": "How to Create a Code of Conduct for an Open-Source Project",
      "summary": "Build a safe and welcoming community for your open-source project with a clear code of conduct. Learn the steps, from defining goals to updating the document, to create guidelines for behavior. Start strong with our expert guidance.",
      "content_html": "<p class=\"lead\">Creating a code of conduct is a first step toward a safe and welcoming community for an open-source project. In many cases, the code of conduct may be created before the community even exists. This can be beneficial as it ensures that the project starts with clear expectations and guidelines for behavior. The process of creating a code of conduct involves several steps, including defining goals and scope, researching existing codes of conduct, drafting the document, reviewing and approving the document, publishing and communicating the code of conduct, and regularly reviewing and updating the document.</p>\n<h2 id=\"why-do-we-need-one\">Why do we need one?</h2>\n<p>By adopting a code of conduct for your open-source project, you can establish clear expectations for participant behavior, which can help foster a positive social atmosphere within your community. In turn, this can not only protect your participants, but also yourself as the project maintainer, as unproductive attitudes from participants can ultimately make you feel drained or unhappy about your work. By being proactive and enforcing a code of conduct, you can facilitate healthy and constructive behavior, which can reduce the likelihood of issues arising and make your project a more welcoming and supportive environment for all.</p>\n<h2 id=\"define-the-goals-and-scope\">Define the Goals and Scope</h2>\n<p>The first step is to define the goals and scope of the project. This involves considering the project’s purpose, its intended audience, and the types of behavior that are expected from contributors and users. The goals of the code of conduct should be clear and concise and should outline the expectations for all contributors, users, maintainers, and community members.</p>\n<p>Defining the goals and scope of a project is the first step in creating a code of conduct. This involves identifying the project’s purpose, intended audience, and expected behavior from contributors and users. The code of conduct should have clear and concise goals that outline the expectations for all community members, including contributors, users, and maintainers.</p>\n<p>Additionally, a code of conduct should also specify where it applies, who it applies to (including sponsors), what actions will be taken if someone violates it, and how individuals can report any violations. Considering “where it applies”, we are often thinking only about issues, pull requests, and discussions, but it can apply also to community events, social media, communication applications, etc.</p>\n<h2 id=\"research-existing-codes-of-conduct\">Research Existing Codes of Conduct</h2>\n<p>Whether the community already exists or not, the next step is to research existing codes of conduct to identify what works and what doesn’t, but also to have a base to work on. This can be done by reviewing codes of conduct from similar projects or industries. The goal is to identify best practices and guidelines that can be incorporated into the code of conduct.</p>\n<h3 id=\"contributor-covenant\">Contributor Covenant</h3>\n<p>The <a href=\"https://www.contributor-covenant.org/\">Contributor Covenant</a> is a widely-used code of conduct to free and open-source software projects, created by <a href=\"https://github.com/CoralineAda\">Coraline Ada Ehmke</a> in 2014. This code of conduct outlines specific behaviors that are expected from contributors, such as being respectful of differing viewpoints, avoiding offensive language, and refraining from harassment or discrimination. The goal of the Contributor Covenant is to ensure that everyone can participate in open-source projects without fear of being marginalized or excluded and to promote a culture of kindness and empathy in the tech industry.</p>\n<p>It has been adopted by thousands of open-source projects and many prominent companies including Google, Intel, GitLab, and open-source projects including Vue.js, Symfony, Bootstrap. The code outlines specific behaviors expected of contributors, such as being respectful of differing viewpoints and avoiding offensive language. In 2021, it has been included in the <a href=\"https://ethicalsource.dev/\">Organization for Ethical Source</a>. The Contributor Covenant has played a significant role in promoting a culture of kindness and empathy within the open source community.</p>\n<p>Adopting the Contributor Covenant as your code of conduct offers several benefits:</p>\n<ul>\n<li>It is widely recognized within the community, meaning that the values of the community can be instantly communicated and understood.</li>\n<li>It has been reviewed and adopted by many which makes it a trusted and reliable option.</li>\n<li>If you are unsure about how to create your own code of conduct, the Contributor Covenant is readily available and can provide a practical starting point for creating conduct that reflects the values of your community.</li>\n<li>It has been <a href=\"https://www.contributor-covenant.org/translations/\">translated into multiple languages</a>, making it accessible and inclusive for a diverse range of contributors.</li>\n</ul>\n<blockquote>\n<p>[!TIP] Looking to make a big impact as an open source contributor?\nTranslate or help to translate the Contributor Covenant into your non-English language. As of September 2026, version 3.0 exists in 9 languages, against 26 for version 2.1: your contribution can help make the open source community more accessible and inclusive. Visit the <a href=\"https://github.com/EthicalSource/contributor_covenant/blob/release/CONTRIBUTING.md#translators-and-native-speakers\">Contributor Covenant GitHub repository</a> for instructions on how to get started and make a significant difference. <a href=\"https://openresource.dev/guide/contributing/non-code-contributions/#translate-what-people-read-first\">Non-Code Contributions Maintainers Actually Want</a> covers translating in general.</p>\n</blockquote>\n<h3 id=\"other-existing-codes-of-conduct\">Other Existing Codes of Conduct</h3>\n<p>There are several other well-known codes of conduct in open source, in addition to the Contributor Covenant, or based on it:</p>\n<ul>\n<li>The <a href=\"https://ubuntu.com/community/ethos/code-of-conduct\">Ubuntu Code of Conduct</a>;</li>\n<li>The <a href=\"https://www.mozilla.org/en-US/about/governance/policies/participation/\">Mozilla Community Participation Guidelines</a> with a very interesting explanation:\n<blockquote cite=\"https://www.mozilla.org/en-US/about/governance/policies/participation/\"><p>“These guidelines have been adapted with modifications from Mozilla’s original Community Participation Guidelines,\nthe <a href=\"https://www.ubuntu.com/about/about-ubuntu/conduct\">Ubuntu Code of Conduct</a>, Mozilla’s <a href=\"https://viewsourceconf.org/berlin-2016/code-of-conduct/\">View Source Conference\nCode of Conduct</a>, and the <a href=\"https://www.rust-lang.org/conduct.html\">Rust Language Code of\nConduct</a>, which are based on Stumptown Syndicate’s <a href=\"https://web.archive.org/web/20200330154000/http://citizencodeofconduct.org/\">Citizen Code of\nConduct</a>. Additional text from the\n<a href=\"http://lgbtq.technology/coc.html\">LGBTQ in Technology Code of Conduct</a> and the <a href=\"http://wiscon.net/policies/anti-harassment/code-of-conduct/\">WisCon code of\nconduct</a>. This document and all associated processes\nare only possible with the hard work of many, many Mozillians.”</p></blockquote>\n</li>\n<li>The <a href=\"https://www.djangoproject.com/conduct/\">Django Code of Conduct</a>;</li>\n<li>The <a href=\"https://www.rust-lang.org/policies/code-of-conduct\">Rust Code of Conduct</a> adapted from the <a href=\"https://blog.izs.me/2012/08/policy-on-trolling/\">Node.js Policy on Trolling</a> as well as the <a href=\"https://www.contributor-covenant.org/version/1/3/0/code-of-conduct/\">Contributor Covenant v1.3.0</a>;</li>\n<li>The <a href=\"https://github.com/cncf/foundation/blob/main/code-of-conduct.md\">CNCF Code of Conduct</a> adapted from the <a href=\"http://contributor-covenant.org/version/2/0/code_of_conduct/\">Contributor Covenant v2.0</a>;</li>\n</ul>\n<p>These are just a few examples of the many codes of conduct that exist in the open source community. Each code of conduct may have its own unique focus and guidelines, but they all share the goal of promoting a respectful and inclusive environment for collaboration and contribution.</p>\n<h2 id=\"draft-the-code-of-conduct\">Draft the Code of Conduct</h2>\n<p>After gathering research and input, the code of conduct can be drafted. The code of conduct should be written in clear and concise language and should be easily understood by all members of the community.</p>\n<p>It should include guidelines on behavior, as well as consequences for violating the code of conduct.</p>\n<p>Specify the actions that will be taken if there is a violation of the code of conduct. Doing so will convey the seriousness with which you take the code of conduct, assure the community that complaints will be fairly and transparently reviewed, and demonstrate your commitment to enforcing the code of conduct. Providing a private way for people to report violations and specifying who will receive those reports matter too. Lastly, it’s important to offer an alternative option for people to report violations if they are related to someone who receives those reports.</p>\n<h2 id=\"review-and-approval\">Review and Approval</h2>\n<p>Once the code of conduct is drafted, it is important to review it with key stakeholders, including legal advisors in some cases, and any other relevant parties. These individuals could provide feedback on the code of conduct and ensure that it is legally sound.</p>\n<h2 id=\"publication-and-communication\">Publication and Communication</h2>\n<p>Once the code of conduct is finalized, it should be published and communicated to the community.</p>\n<p>This can be done through the:</p>\n<ul>\n<li>project’s website or documentation\n<ul>\n<li>with a link in the footer or elsewhere to a code of conduct stored anywhere.</li>\n<li>by creating a dedicated page like in <a href=\"https://about.gitlab.com/community/contribute/code-of-conduct/\">GitLab Code of Conduct</a>.</li>\n</ul>\n</li>\n<li>other communication channels like Slack, Discord, Mattermost, etc..\n<ul>\n<li>In <a href=\"https://astro.build/chat\">Astro Lounge Discord</a>, they have it for example in their “rules” channel which contains a link to their code of conduct stored on GitHub.</li>\n</ul>\n</li>\n<li>source code repositories.\n<ul>\n<li>For open-source projects, this is mainly where you’re going to find it at the root level of the main repository of the organization.</li>\n</ul>\n</li>\n</ul>\n<p>It is important to ensure that all members of the community are aware of the code of conduct and understand its expectations. But it is also important to have it available accessible by anyone and in order to link it if one must be reminded of the rules.</p>\n<h3 id=\"how-to-add-it-to-source-code-repositories\">How to add it to source code repositories</h3>\n<h4 id=\"github-provides-some-templates\">GitHub Provides Some Templates</h4>\n<p>GitHub offers guidance on creating a Code of Conduct through templates available on their website. When adding a new <code>CODE_OF_CONDUCT</code> or <code>CODE_OF_CONDUCT.md</code> file through the interface at the root level of your repository, you can select from two different templates to add to your project:</p>\n<ul>\n<li>Contributor Covenant;</li>\n<li>Citizen Code Of Conduct;</li>\n</ul>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/add-a-code-of-conduct-to-your-project-1.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/add-a-code-of-conduct-to-your-project-1.png\" alt=\"GitHub's Add a code of conduct page: Contributor Covenant and Citizen Code Of Conduct on the left, a prompt to pick one.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"190\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"GitHub's Add a code of conduct page: Contributor Covenant and Citizen Code Of Conduct on the left, a prompt to pick one.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/add-a-code-of-conduct-to-your-project-1.png\" alt=\"GitHub's Add a code of conduct page: Contributor Covenant and Citizen Code Of Conduct on the left, a prompt to pick one.\" width=\"720\" height=\"190\" data-astro-cid-lanmunwp></dialog></div>\n<p>You can then complete your code of conduct by filling out a simple form with the required information.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/add-a-code-of-conduct-to-your-project-2.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/add-a-code-of-conduct-to-your-project-2.png\" alt=\"The Contributor Covenant template on GitHub, with a form on the right for the contact method and a Review and submit button.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"482\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The Contributor Covenant template on GitHub, with a form on the right for the contact method and a Review and submit button.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/add-a-code-of-conduct-to-your-project-2.png\" alt=\"The Contributor Covenant template on GitHub, with a form on the right for the contact method and a Review and submit button.\" width=\"720\" height=\"482\" data-astro-cid-lanmunwp></dialog></div>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/add-a-code-of-conduct-to-your-project-3.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/add-a-code-of-conduct-to-your-project-3.png\" alt=\"The Citizen Code of Conduct template on GitHub, with a form of several fields on the right and a Review and submit button.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"502\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The Citizen Code of Conduct template on GitHub, with a form of several fields on the right and a Review and submit button.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/add-a-code-of-conduct-to-your-project-3.png\" alt=\"The Citizen Code of Conduct template on GitHub, with a form of several fields on the right and a Review and submit button.\" width=\"720\" height=\"502\" data-astro-cid-lanmunwp></dialog></div>\n<p>After reviewing your changes, submit them and a <code>CODE_OF_CONDUCT.md</code> file will be created at the root level of your repository. You can then view a special display by visiting your repository. An example of this rendering can be seen in the <a href=\"https://github.com/community/community\">GitHub Community repository</a>.</p>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://openresource.dev/images/add-a-code-of-conduct-to-your-project-4.png\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://openresource.dev/images/add-a-code-of-conduct-to-your-project-4.png\" alt=\"The Code of conduct link GitHub shows in a repository's sidebar, with a heart-and-handshake icon.\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"310\" height=\"82\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"The Code of conduct link GitHub shows in a repository's sidebar, with a heart-and-handshake icon.\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://openresource.dev/images/add-a-code-of-conduct-to-your-project-4.png\" alt=\"The Code of conduct link GitHub shows in a repository's sidebar, with a heart-and-handshake icon.\" width=\"310\" height=\"82\" data-astro-cid-lanmunwp></dialog></div>\n<p>This article may be obsolete in the future regarding some details, please check the latest version of the GitHub documentation for <a href=\"https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-code-of-conduct-to-your-project\">Adding a code of conduct to your project</a>.</p>\n<h4 id=\"manually\">Manually</h4>\n<p>Adding a code of conduct in your repository is a straightforward process that works for all source code repository services, including GitHub, GitLab, BitBucket, and more. Simply create a <code>CODE_OF_CONDUCT</code> or <code>CODE_OF_CONDUCT.md</code> file at the root level of your repository, depending on whether you prefer the Markdown or simple text format.</p>\n<p>While GitHub provides guidance with templates, you can in fact use any code of conduct you prefer. Except for GitHub, even if most of the source code repository services do not offer a dedicated display in repositories for code of conduct files, open-source projects should still incorporate one, as it is considered a best practice. By storing it at the root level of the project, it can be easily referenced and used as a standard for appropriate behavior within the community.</p>\n<p>If you have selected the Contributor Covenant as your code of conduct, there is a neat trick to add a badge to your README.md file. You can do this by adding the following code:</p>\n<pre class=\"astro-code deramond-dark d-code\" style=\"background-color:#16181E;color:#E6E8EC;overflow-x:auto\" tabindex=\"0\" data-language=\"md\"><code><span class=\"line\"><span style=\"color:#E6E8EC\">[</span><span style=\"color:#E6E8EC\">![</span><span style=\"color:#3AB9BF\">Contributor Covenant</span><span style=\"color:#E6E8EC\">](</span><span style=\"color:#3AB9BF\">https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg</span><span style=\"color:#E6E8EC\">)</span><span style=\"color:#E6E8EC\">](</span><span style=\"color:#3AB9BF\">code_of_conduct.md</span><span style=\"color:#E6E8EC\">)</span></span></code></pre>\n<div class=\"content-image\" data-astro-cid-lanmunwp><a href=\"https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg\" aria-haspopup=\"dialog\" data-astro-cid-lanmunwp><img src=\"https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg\" alt=\"Contributor Covenant Badge\" data-astro-cid-lanmunwp=\"true\" loading=\"lazy\" decoding=\"async\" width=\"156\" height=\"20\"><span class=\"d-visually-hidden\" data-astro-cid-lanmunwp>(full size)</span></a><dialog aria-label=\"Contributor Covenant Badge\" data-astro-cid-lanmunwp><form method=\"dialog\" data-astro-cid-lanmunwp><button class=\"d-mono\" data-astro-cid-lanmunwp>Close</button></form><img data-src=\"https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg\" alt=\"Contributor Covenant Badge\" width=\"156\" height=\"20\" data-astro-cid-lanmunwp></dialog></div>\n<h4 id=\"reusable-code-of-conduct-in-github\">Reusable Code of Conduct in GitHub</h4>\n<p>GitHub provides a convenient feature for reusing a code of conduct across multiple repositories by creating a default code of conduct. This default code of conduct is part of a list of default community health files, including <code>CONTRIBUTING</code>, <code>FUNDING</code>, and issue and pull request templates. Any repository owned by the account that does not have its own code of conduct file will use this default one. To set this up, you can create a <code>.github</code> public repository and add a <code>CODE_OF_CONDUCT</code> or <code>CODE_OF_CONDUCT.md</code> file at the root level of the repository.</p>\n<p>To see an example of how this works, you can take a look at <a href=\"https://github.com/Open-reSource/.github\">our <code>.github</code> public GitHub repository</a>.</p>\n<p>This article may be obsolete in the future regarding some details, please check the latest version of the GitHub documentation for <a href=\"https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/creating-a-default-community-health-file\">Creating a default community health file</a>.</p>\n<h2 id=\"regular-review-and-updates\">Regular Review and Updates</h2>\n<p>Finally, the code of conduct should be reviewed and updated regularly to ensure that it remains relevant and effective. This review process should involve the entire community and should be conducted at regular intervals, such as annually.</p>\n<p>A useful tip for those using the Contributor Covenant is to subscribe to release notifications <a href=\"https://github.com/EthicalSource/contributor_covenant\">in project’s GitHub repository</a>. This way, you can easily stay informed and be alerted when a new version of the code of conduct is released, ensuring that your project stays up-to-date.</p>\n<h2 id=\"enforcing-the-code-of-conduct\">Enforcing the Code of Conduct</h2>\n<p>It’s rare, but in any community, there may come a time when a member violates the code of conduct. When this happens, there are several steps that moderators or maintainers can take to address the situation.</p>\n<p>The first step is to gather information about the situation. It’s important to treat each community member’s voice as important as your own and take any reports seriously. Investigate the matter even if it doesn’t match your own experience with that person. Before responding, take time to understand what happened by reading through the person’s past comments and conversations to better understand who they are and why they might have acted in such a way. Try to gather perspectives other than your own about this person and their behavior.</p>\n<p>Once you have gathered sufficient information, it’s important to take appropriate action. Your goal as a moderator or maintainer is to foster a safe, respectful, and collaborative environment. Consider not only how to deal with the situation in question, but how your response will affect the rest of your community’s behavior and expectations moving forward. Depending on the severity of the violation, you may choose to give the person in question a public warning and explain how their behavior negatively impacted others or privately reach out to the person to explain how their behavior negatively impacted others. In some cases, stronger action may be necessary, such as suspending or permanently banning the person from the project.</p>",
      "date_published": "2023-04-13T00:00:00.000Z",
      "date_modified": "2026-10-03T00:00:00.000Z",
      "tags": [
        "Community",
        "Contribution"
      ]
    }
  ]
}