Documentation Index Fetch the complete documentation index at: https://mintlify.com/betterdiscord/betterdiscord/llms.txt
Use this file to discover all available pages before exploring further.
BdApi is the global API provided by BetterDiscord for plugin developers. It offers utilities for patching, data storage, UI creation, and accessing Discord’s internals.
Accessing BdApi
BdApi is available globally:
BdApi . UI . showToast ( "Hello World!" );
Plugin-specific API instance
Create a bound instance for automatic plugin name tracking:
const api = new BdApi ( "MyPlugin" );
// All calls are automatically associated with your plugin
api . Logger . info ( "Starting up" );
api . Data . save ( "config" , { enabled: true });
Core namespaces
Patcher
Modify existing functions to change Discord’s behavior.
before()
Run code before the original function:
BdApi . Patcher . before ( "MyPlugin" , someModule , "functionName" , ( thisObject , args ) => {
// Modify arguments
args [ 0 ] = "modified value" ;
});
after()
Run code after the original function and modify the return value:
BdApi . Patcher . after ( "MyPlugin" , someModule , "functionName" , ( thisObject , args , returnValue ) => {
// Modify return value
if ( returnValue ) {
returnValue . modified = true ;
}
return returnValue ;
});
instead()
Replace the original function entirely:
BdApi . Patcher . instead ( "MyPlugin" , someModule , "functionName" , ( thisObject , args , originalFunction ) => {
// Optionally call original
const result = originalFunction . call ( thisObject , ... args );
// Return custom value
return "custom return value" ;
});
unpatchAll()
Remove all patches created by your plugin:
BdApi . Patcher . unpatchAll ( "MyPlugin" );
Always call unpatchAll() in your plugin’s stop() method to prevent conflicts.
Data
Persist plugin data to disk.
save()
Save data with a key:
BdApi . Data . save ( "MyPlugin" , "settings" , {
enabled: true ,
theme: "dark"
});
With bound API:
const api = new BdApi ( "MyPlugin" );
api . Data . save ( "settings" , { enabled: true });
load()
Load previously saved data:
const settings = BdApi . Data . load ( "MyPlugin" , "settings" );
if ( ! settings ) {
// Use defaults
settings = { enabled: true , theme: "dark" };
}
delete()
Delete stored data:
BdApi . Data . delete ( "MyPlugin" , "settings" );
Webpack
Find and access Discord’s internal modules.
getModule()
Find a single module:
const MessageActions = BdApi . Webpack . getModule (
BdApi . Webpack . Filters . byKeys ( "sendMessage" )
);
With options:
const module = BdApi . Webpack . getModule (
BdApi . Webpack . Filters . byKeys ( "someFunction" ),
{ searchExports: true , defaultExport: false }
);
getModules()
Find multiple matching modules:
const allModules = BdApi . Webpack . getModules (
BdApi . Webpack . Filters . byKeys ( "render" )
);
Filters
Built-in filters for finding modules:
byKeys
byStrings
byDisplayName
byStoreName
combine
// Find by property names
const filter = BdApi . Webpack . Filters . byKeys ( "sendMessage" , "editMessage" );
Stores
Access Discord’s Flux stores directly:
const { UserStore , ChannelStore , GuildStore } = BdApi . Webpack . Stores ;
const currentUser = UserStore . getCurrentUser ();
const channel = ChannelStore . getChannel ( "123456789" );
Create user interface elements.
showToast()
Display a toast notification:
BdApi . UI . showToast ( "Operation successful!" , {
type: "success" ,
icon: true ,
timeout: 3000
});
Toast type: "info", "success", "warning", "error" (default: "info")
Whether to show an icon (default: true)
Duration in milliseconds (default: 3000)
showNotice()
Display a notice banner:
const close = BdApi . UI . showNotice ( "Update available!" , {
type: "info" ,
buttons: [{
label: "Update" ,
onClick : () => {
// Handle update
}
}],
timeout: 10000
});
// Close manually
close ();
alert()
Show an alert modal:
BdApi . UI . alert ( "Warning" , "This action cannot be undone." );
showConfirmationModal()
Show a confirmation dialog:
BdApi . UI . showConfirmationModal (
"Delete Item" ,
"Are you sure you want to delete this item?" ,
{
confirmText: "Delete" ,
cancelText: "Cancel" ,
danger: true ,
onConfirm : () => {
// Delete the item
},
onCancel : () => {
// Cancelled
}
}
);
buildSettingsPanel()
Create a settings panel (see Settings for details):
BdApi . UI . buildSettingsPanel ({
settings: [
{
type: "switch" ,
id: "enabled" ,
name: "Enable Feature" ,
value: true ,
onChange : ( value ) => console . log ( value )
}
]
});
Logger
Log messages with proper formatting.
const api = new BdApi ( "MyPlugin" );
api . Logger . log ( "General message" );
api . Logger . info ( "Informational message" );
api . Logger . warn ( "Warning message" );
api . Logger . error ( "Error message" );
api . Logger . debug ( "Debug message" );
Output includes your plugin name:
[MyPlugin] Informational message
DOM
Manipulate the DOM safely.
addStyle()
Add CSS to the page:
BdApi . DOM . addStyle ( "MyPlugin" , `
.my-custom-class {
color: red;
font-weight: bold;
}
` );
removeStyle()
Remove injected CSS:
BdApi . DOM . removeStyle ( "MyPlugin" );
React and ReactDOM
Access Discord’s React instance:
const { React , ReactDOM } = BdApi ;
const MyComponent = () => {
const [ count , setCount ] = React . useState ( 0 );
return React . createElement ( "button" , {
onClick : () => setCount ( count + 1 )
}, `Clicked ${ count } times` );
};
Utils
Utility functions.
getNestedProp()
Safely access nested properties:
const value = BdApi . Utils . getNestedProp ( obj , "deeply.nested.property" );
className()
Generate className strings:
const className = BdApi . Utils . className (
"base-class" ,
condition && "conditional-class" ,
{ "active" : isActive }
);
Plugins
Manage other plugins.
// Get plugin folder path
const folder = BdApi . Plugins . folder ;
// Check if a plugin is enabled
const isEnabled = BdApi . Plugins . isEnabled ( "OtherPlugin" );
// Enable/disable plugins
BdApi . Plugins . enable ( "OtherPlugin" );
BdApi . Plugins . disable ( "OtherPlugin" );
BdApi . Plugins . toggle ( "OtherPlugin" );
// Reload a plugin
BdApi . Plugins . reload ( "OtherPlugin" );
// Get plugin instance
const plugin = BdApi . Plugins . get ( "OtherPlugin" );
// Get all plugins
const allPlugins = BdApi . Plugins . getAll ();
Managing other plugins should be done carefully. Only enable/disable plugins with explicit user consent.
Add items to context menus.
BdApi . ContextMenu . patch ( "user-context" , ( returnValue , props ) => {
returnValue . props . children . push (
BdApi . ContextMenu . buildItem ({
type: "text" ,
label: "My Custom Option" ,
action : () => {
console . log ( "Clicked!" , props );
}
})
);
});
Commands
Register slash commands.
const api = new BdApi ( "MyPlugin" );
api . Commands . register ({
command: "hello" ,
description: "Say hello" ,
options: [
{
name: "name" ,
description: "Name to greet" ,
type: "STRING" ,
required: false
}
],
execute : ( args ) => {
const name = args . name || "World" ;
return { content: `Hello, ${ name } !` };
}
});
Unregister in stop():
api . Commands . unregister ( "hello" );
Components
Access to BetterDiscord React components. See Settings for component documentation.
const { Components } = BdApi ;
// Available components
Components . SettingItem
Components . SwitchInput
Components . SliderInput
Components . TextInput
Components . DropdownInput
Components . NumberInput
Components . RadioInput
Components . KeybindInput
Components . ColorInput
Components . SearchInput
Components . SettingGroup
Components . ErrorBoundary
Components . Text
Components . Flex
Components . Button
Components . Spinner
Components . Tooltip
Version info
Get BetterDiscord version:
console . log ( BdApi . version ); // e.g., "1.9.0"