# Developer Guides

**URL:** https://meta.discourse.org/c/documentation/developer-guides/56.md

[Latest](https://meta.discourse.org/latest.md) · [Categories](https://meta.discourse.org/categories.md) · [Tags](https://meta.discourse.org/tags.md)

---

## [Developer Guides Index](https://meta.discourse.org/t/developer-guides-index/308036)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 0\
**Last updated:** [May 15, 2024, 6:05am UTC](https://meta.discourse.org/t/developer-guides-index/308036 "2024-05-15T06:05:51Z")

</div>

Documentation about extending Discourse with plugins, themes, and theme components, working with the core code, and using the Discourse API. Introduction Introduction: Introduction to Discourse Development Development…

---

## [Using the AI bot via the Discourse API](https://meta.discourse.org/t/using-the-ai-bot-via-the-discourse-api/412826)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 0\
**Last updated:** [September 19, 2026, 5:45am UTC](https://meta.discourse.org/t/using-the-ai-bot-via-the-discourse-api/412826 "2026-09-19T05:45:35Z")

</div>

Overview Discourse AI exposes an admin/API endpoint for streaming an AI Agent reply over a raw chunked HTTP response. Protocol: Raw chunked HTTP transfer encoding (NOT Server-Sent Events). Implementation: Hijacks the…

---

## [Developer's guide to Markdown extensions](https://meta.discourse.org/t/developers-guide-to-markdown-extensions/66023)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 1\
**Last updated:** [June 1, 2026, 8:45am UTC](https://meta.discourse.org/t/developers-guide-to-markdown-extensions/66023 "2026-06-01T08:45:53Z")

</div>

Discourse uses a Markdown engine called Markdown-it. Here are some dev notes that will help you either fix bugs in core or create your new plugins. The Basics Discourse only contains a few helpers on top of the engine,…

---

## [Adding a new 'managed' authentication method to Discourse](https://meta.discourse.org/t/adding-a-new-managed-authentication-method-to-discourse/106695)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 2\
**Last updated:** [November 29, 2023, 7:48am UTC](https://meta.discourse.org/t/adding-a-new-managed-authentication-method-to-discourse/106695 "2023-11-29T07:48:14Z")

</div>

Continuing from Future Social Authentication Improvements… We are now in the process of moving all ‘associated account’ information into a single database table. This will help to significantly reduce duplicated logic, …

---

## [Theme Developer Tutorial: 7. Wrapping up](https://meta.discourse.org/t/theme-developer-tutorial-7-wrapping-up/357802)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 0\
**Last updated:** [March 18, 2025, 3:59pm UTC](https://meta.discourse.org/t/theme-developer-tutorial-7-wrapping-up/357802 "2025-03-18T15:59:12Z")

</div>

This tutorial has been a whistle-stop tour through the process of creating a Discourse theme and experimenting with a few of the most common APIs. Of course, there’s plenty more to learn, so let’s map out some more place…

---

## [Theme Developer Tutorial: 6. Using the JS API](https://meta.discourse.org/t/theme-developer-tutorial-6-using-the-js-api/357801)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 3\
**Last updated:** [April 14, 2025, 11:16pm UTC](https://meta.discourse.org/t/theme-developer-tutorial-6-using-the-js-api/357801 "2025-04-14T23:16:42Z")

</div>

In the last couple of chapters, we’ve explored how to use the JavaScript API to render content into outlets. renderInOutlet is the most commonly-used API, but there are a ton more! In this chapter we’ll try out a few of …

---

## [Add settings to your Discourse theme](https://meta.discourse.org/t/add-settings-to-your-discourse-theme/82557)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 6\
**Last updated:** [July 8, 2025, 7:43pm UTC](https://meta.discourse.org/t/add-settings-to-your-discourse-theme/82557 "2025-07-08T19:43:17Z")

</div>

Discourse has the ability for themes to have “settings” that can be added by theme developers to allow site owners to customize themes through UI without having to change any line of code and worry about losing their cha…

---

## [Theme Developer Quick Reference Guide](https://meta.discourse.org/t/theme-developer-quick-reference-guide/110448)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 2\
**Last updated:** [June 28, 2021, 5:13pm UTC](https://meta.discourse.org/t/theme-developer-quick-reference-guide/110448 "2021-06-28T17:13:16Z")

</div>

As themes grow more powerful, there’s more to remember about how they work. We have loads of detailed documentation under #theme-guides, but if you just need something to jog your memory, this guide may help. General Re…

---

## [Designing for Responsive Widths (Breakpoints, Viewport & Containers)](https://meta.discourse.org/t/designing-for-responsive-widths-breakpoints-viewport-containers/409279)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 0\
**Last updated:** [August 4, 2026, 3:57pm UTC](https://meta.discourse.org/t/designing-for-responsive-widths-breakpoints-viewport-containers/409279 "2026-08-04T15:57:20Z")

</div>

This document outlines the APIs used to adapt Discourse’s user interface to different widths — both the browser viewport, and individual containers on the page. We design “mobile first” and then add customizations for l…

---

## [Designing for Different Devices (Touch & Hover)](https://meta.discourse.org/t/designing-for-different-devices-touch-hover/367810)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 14\
**Last updated:** [January 25, 2026, 9:34pm UTC](https://meta.discourse.org/t/designing-for-different-devices-touch-hover/367810 "2026-01-25T21:34:26Z")

</div>

This document outlines the APIs used to adapt Discourse’s user interface for different devices. Touch & Hover Some devices only have touchscreens, some only have a traditional mouse pointer, and some have both. Importan…

---

## [Guidelines for CSS classes using BEM](https://meta.discourse.org/t/guidelines-for-css-classes-using-bem/361851)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 0\
**Last updated:** [April 15, 2025, 5:48am UTC](https://meta.discourse.org/t/guidelines-for-css-classes-using-bem/361851 "2025-04-15T05:48:23Z")

</div>

Background When writing CSS classes for Discourse components, themes, or plugins, we follow a modified variant of Block Element Modifier (BEM). Following these guidelines will make it much less likely for CSS conflicts t…

---

## [Customizing the topic list](https://meta.discourse.org/t/customizing-the-topic-list/350411)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 0\
**Last updated:** [February 4, 2025, 10:40am UTC](https://meta.discourse.org/t/customizing-the-topic-list/350411 "2025-02-04T10:40:33Z")

</div>

The topic-list is one of the most-used and most-customized user-interfaces in Discourse. There are many different tools available to theme and plugin developers to achieve this customization, each with their own advantag…

---

## [Using the DModal API to render Modal windows (aka popups/dialogs) in Discourse](https://meta.discourse.org/t/using-the-dmodal-api-to-render-modal-windows-aka-popups-dialogs-in-discourse/268304)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 0\
**Last updated:** [July 3, 2023, 9:52am UTC](https://meta.discourse.org/t/using-the-dmodal-api-to-render-modal-windows-aka-popups-dialogs-in-discourse/268304 "2023-07-03T09:52:06Z")

</div>

Discourse 3.1.0.beta6 ships with a brand new \<DModal\> component-based API. DModal is part of the UI kit and is imported from discourse/ui-kit/d-modal. :information\_source: This supersedes the old controller-based API, …

---

## [The UI kit of shared Discourse components, helpers, and modifiers](https://meta.discourse.org/t/the-ui-kit-of-shared-discourse-components-helpers-and-modifiers/411319)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 0\
**Last updated:** [August 31, 2026, 5:34pm UTC](https://meta.discourse.org/t/the-ui-kit-of-shared-discourse-components-helpers-and-modifiers/411319 "2026-08-31T17:34:16Z")

</div>

ui-kit is the layer of reusable, domain-free building blocks that core, plugins, and themes compose their interfaces from. It lives under frontend/discourse/app/ui-kit/ and ships three kinds of primitive: Components:…

---

## [Set up Discourse for development on Fedora Linux](https://meta.discourse.org/t/set-up-discourse-for-development-on-fedora-linux/163348)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 13\
**Last updated:** [June 19, 2026, 5:20am UTC](https://meta.discourse.org/t/set-up-discourse-for-development-on-fedora-linux/163348 "2026-06-19T05:20:22Z")

</div>

This guide has been tested against a fresh install of Fedora 31 and 33, but may work on older versions that also use dnf as the package management tool. This is not an official guide but may be useful for other developer…

---

## [Install Discourse on Windows for development](https://meta.discourse.org/t/install-discourse-on-windows-for-development/75149)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 16\
**Last updated:** [April 22, 2026, 10:18am UTC](https://meta.discourse.org/t/install-discourse-on-windows-for-development/75149 "2026-04-22T10:18:42Z")

</div>

:information\_source: This tutorial has been tested on Windows 10 and 11. To set up a development environment for Discourse on Windows, you can do it using Windows Subsystem for Linux feature. This setup requires the …

---

## [Install Discourse on Ubuntu or Debian for Development](https://meta.discourse.org/t/install-discourse-on-ubuntu-or-debian-for-development/14727)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 83\
**Last updated:** [June 22, 2025, 12:31am UTC](https://meta.discourse.org/t/install-discourse-on-ubuntu-or-debian-for-development/14727 "2025-06-22T00:31:14Z")

</div>

:warning: This guide covers installation instructions in a development environment. For a production guide see: Install Discourse in production with the official supported instructions So you want to set up Discour…

---

## [Install Discourse on macOS for development](https://meta.discourse.org/t/install-discourse-on-macos-for-development/15772)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 102\
**Last updated:** [April 24, 2026, 6:38pm UTC](https://meta.discourse.org/t/install-discourse-on-macos-for-development/15772 "2026-04-24T18:38:20Z")

</div>

:warning: This guide covers installation instructions for a macOS development environment, for production guides see: Install Discourse in production with the official supported instructions So you want to set up Disc…

---

## [Bundle splitting for plugins](https://meta.discourse.org/t/bundle-splitting-for-plugins/411886)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 0\
**Last updated:** [September 8, 2026, 11:07am UTC](https://meta.discourse.org/t/bundle-splitting-for-plugins/411886 "2026-09-08T11:07:29Z")

</div>

By default, every javascript module in a plugin is loaded when Discourse boots. This guide describes the staticModules system, which allows code to be automatically loaded on-demand, thereby improving initial boot times. …

---

## [Using Transformers to customize client-side values and behavior](https://meta.discourse.org/t/using-transformers-to-customize-client-side-values-and-behavior/349954)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 2\
**Last updated:** [September 5, 2026, 2:53am UTC](https://meta.discourse.org/t/using-transformers-to-customize-client-side-values-and-behavior/349954 "2026-09-05T02:53:05Z")

</div>

Discourse core includes a number of “transformer” hooks which can be used to customize client behavior. These fall into two categories: Value Transformers take an output from Discourse core, and optionally modify it, …

---

## [Discourse toolkit to render forms](https://meta.discourse.org/t/discourse-toolkit-to-render-forms/326439)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 28\
**Last updated:** [December 23, 2025, 5:55pm UTC](https://meta.discourse.org/t/discourse-toolkit-to-render-forms/326439 "2025-12-23T17:55:56Z")

</div>

Basic Usage FormKit exposes a single component as its public API: \<Form /\>. All other elements are yielded as contextual components, modifiers, or plain data. Every form is composed of one or multiple fields, represen…

---

## [Drag, resize, and gesture primitives](https://meta.discourse.org/t/drag-resize-and-gesture-primitives/410549)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 0\
**Last updated:** [August 20, 2026, 4:44pm UTC](https://meta.discourse.org/t/drag-resize-and-gesture-primitives/410549 "2026-08-20T16:44:52Z")

</div>

ui-kit ships the input-driven gesture primitives: dragging a payload onto a target, resizing a region, and reading a swipe or a pointer drag. This page is the usage reference. Each primitive’s own TSDoc carries the f…

---

## [JavaScript type hinting & validation (typescript)](https://meta.discourse.org/t/javascript-type-hinting-validation-typescript/395136)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 0\
**Last updated:** [February 4, 2026, 10:38am UTC](https://meta.discourse.org/t/javascript-type-hinting-validation-typescript/395136 "2026-02-04T10:38:25Z")

</div>

Discourse ships type information for its JavaScript code. This can provide inline documentation, autocomplete, and other useful IDE features. It can also be used for some basic type validation, using the @ts-check direct…

---

## [AppEvents Triggers Reference](https://meta.discourse.org/t/appevents-triggers-reference/338465)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 0\
**Last updated:** [November 26, 2024, 10:20am UTC](https://meta.discourse.org/t/appevents-triggers-reference/338465 "2024-11-26T10:20:08Z")

</div>

AppEvents The AppEvent system in Discourse provides a pub/sub mechanism for handling UI updates and component interactions - and these events are triggered via calls of AppEvent.trigger. This topic consolidates a list…

---

## [Write end-to-end system specs for the Discourse user interface](https://meta.discourse.org/t/write-end-to-end-system-specs-for-the-discourse-user-interface/325937)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 3\
**Last updated:** [August 28, 2025, 2:51pm UTC](https://meta.discourse.org/t/write-end-to-end-system-specs-for-the-discourse-user-interface/325937 "2025-08-28T14:51:13Z")

</div>

Background Rails system specs are used to simulate the actions of a real user using the app in a browser. We use the Playwright ruby driver which is becoming an industry standard. The tests run locally and in CI out of t…

---

## [Using service objects in Discourse](https://meta.discourse.org/t/using-service-objects-in-discourse/333641)

<div class="topic-metadata">

**Author:** [@system](https://meta.discourse.org/u/system)\
**Replies:** 0\
**Last updated:** [October 30, 2024, 3:56pm UTC](https://meta.discourse.org/t/using-service-objects-in-discourse/333641 "2024-10-30T15:56:38Z")

</div>

Overview A service is a small object that encompasses business logic for a given action. From outside, it should be seen as a sort of black box. You provide it with parameters, it runs (including all the side effects it…

---

## [(not recommended) Overriding Discourse templates from a Theme or Plugin](https://meta.discourse.org/t/not-recommended-overriding-discourse-templates-from-a-theme-or-plugin/247487)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 9\
**Last updated:** [March 7, 2024, 1:20pm UTC](https://meta.discourse.org/t/not-recommended-overriding-discourse-templates-from-a-theme-or-plugin/247487 "2024-03-07T13:20:54Z")

</div>

Ideally, when customizing Discourse via themes/plugins, you should use CSS, the JavaScript Plugin API, or plugin outlets. If none of these work for your use-case, feel free to open a PR to Discourse core or start a Devel…

---

## [Preventing accidental serialization of ActiveRecord models](https://meta.discourse.org/t/preventing-accidental-serialization-of-activerecord-models/314495)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 2\
**Last updated:** [July 23, 2024, 5:59pm UTC](https://meta.discourse.org/t/preventing-accidental-serialization-of-activerecord-models/314495 "2024-07-23T17:59:58Z")

</div>

We’ve introduced a patch to prevent the accidental serialization of ActiveRecord models without specifying the fields to be serialized. This change ensures that we control which fields are included, avoiding potential is…

---

## [Creating Routes in Discourse and Showing Data](https://meta.discourse.org/t/creating-routes-in-discourse-and-showing-data/48827)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 0\
**Last updated:** [August 18, 2016, 8:18pm UTC](https://meta.discourse.org/t/creating-routes-in-discourse-and-showing-data/48827 "2016-08-18T20:18:49Z")

</div>

Over time Discourse has grown in complexity and it can be daunting for beginners to understand how data gets all the way from the back end Ruby on Rails application to the Ember.js application in front. This tutorial is…

---

## [Using modifyClass to change core behavior](https://meta.discourse.org/t/using-modifyclass-to-change-core-behavior/262064)

<div class="topic-metadata">

**Author:** [@Discourse](https://meta.discourse.org/u/Discourse)\
**Replies:** 6\
**Last updated:** [March 4, 2026, 7:13am UTC](https://meta.discourse.org/t/using-modifyclass-to-change-core-behavior/262064 "2026-03-04T07:13:43Z")

</div>

For advanced themes and plugins, Discourse offers the modifyClass system. This allows you to extend and override functionality in many of core’s javascript classes. When to use modifyClass modifyClass should be a last r…

[Next page](https://meta.discourse.org/c/documentation/developer-guides/56.md?page=1)
