Here you’ll have a full tutorial on how to make a plugin for Teams but (actually) good.Documentation Index
Fetch the complete documentation index at: https://docs.teamsbutactuallygood.dev/llms.txt
Use this file to discover all available pages before exploring further.
If you’re lost or don’t know how to do something, don’t hesitate to check how the official plugins work, that might help you a lot
Setup
You shouldn’t add your plugins insrc/teams-plugins, since this folder is reserved for official plugins. Instead, create your own folder called user-plugins in src (src/user-plugins), and work on your plugins there.
Each plugin must have either an index.ts or an index.tsx as its entry point, and must export the plugin object as default:
Plugin structure
Here is the full interface of a plugin:name
name
The name of the plugin. Must be unique.
description (optional)
description (optional)
A short description of what the plugin does, shown in the settings UI.
author (optional)
author (optional)
enableByDefault (optional)
enableByDefault (optional)
Used to enable plugins by default. Official non-essential plugin won’t use this, but you’re free to use it for your own plugins.
patches
patches
An array of patches to apply to Teams’ webpack modules. Can be an empty array if the plugin doesn’t need to patch anything. See the Patches section for more info.
mainEntry (optional)
mainEntry (optional)
A function called on every
DOMContentLoaded event (i.e. on every page navigation in Teams). Useful for plugins that don’t need to patch anything but still need to run code.onChangeObserved (optional)
onChangeObserved (optional)
A function called when a DOM change is observed.
settingsDef (optional)
settingsDef (optional)
Defines the settings of the plugin. Used by the UI to render the settings controls. See the Settings section for more info.
Simple plugin example
Here is a simple plugin that only usesmainEntry, without any patches:
Patches
Patches let you modify Teams’ internal webpack modules at runtime. A patch has afind to locate the module, and a replacement array to modify it.
find: astringorRegExpused to identify the target webpack module in Teams’ bundlereplacement: one or more{ match, replace }pairs applied to the matched module.matchmust be aRegExp, andreplaceis a string (supports capture groups like$1,$2…)
Settings
You can define settings for your plugin usingsettingsDef. TBAG will automatically render the corresponding controls in the settings UI. The current values are available at runtime via this.settings.
If a setting has restartNeeded: true, a restart button will appear in the UI when the user changes that setting.
Here are all the available setting types:
OptionType.BOOLEAN
OptionType.BOOLEAN
A simple toggle switch.
OptionType.STRING
OptionType.STRING
A text input. Can be multiline.
OptionType.NUMBER
OptionType.NUMBER
A number input.
OptionType.BIGINT
OptionType.BIGINT
Same as NUMBER but for BigInt values.
OptionType.SELECT
OptionType.SELECT
A dropdown with predefined options.
OptionType.SLIDER
OptionType.SLIDER
A slider with defined markers.
OptionType.COMPONENT
OptionType.COMPONENT
Renders a custom React component as the setting control. The component receives
setValue, value, option and ReactLib (Teams’ React instance) as props.OptionType.CUSTOM
OptionType.CUSTOM
For storing arbitrary values that don’t fit any other type, without rendering any UI control.
COMPONENT and CUSTOM) also support these common fields:
