Getting Started
This guide will walk you through creating your first Noctalia plugin.
Prerequisites
Section titled “Prerequisites”- Noctalia Shell installed and running
- Basic knowledge of QML (Qt Quick)
- Text editor of your choice
- Git (for submitting to the plugin registry)
Step 1: Set Up Your Plugin Directory
Section titled “Step 1: Set Up Your Plugin Directory”Plugins are stored in ~/.config/noctalia/plugins/. You can develop directly in this directory or use a separate location and symlink it.
# Option 1: Develop in the plugins directorycd ~/.config/noctalia/plugins/mkdir my-plugincd my-plugin
# Option 2: Develop elsewhere and symlinkmkdir ~/dev/my-noctalia-plugincd ~/.config/noctalia/plugins/ln -s ~/dev/my-noctalia-plugin my-pluginStep 2: Create the Manifest
Section titled “Step 2: Create the Manifest”Every plugin must have a manifest.json file. Create it with this minimal structure:
{ "id": "my-plugin", "name": "My Plugin", "version": "1.0.0", "minNoctaliaVersion": "3.6.0", "author": "Your Name", "license": "MIT", "repository": "https://github.com/yourusername/noctalia-plugins", "description": "A simple example plugin", "entryPoints": { "barWidget": "BarWidget.qml" }, "dependencies": { "plugins": [] }, "metadata": { "defaultSettings": {} }}Step 3: Create a Bar Widget
Section titled “Step 3: Create a Bar Widget”Let’s create a simple bar widget that displays an icon and text. Create BarWidget.qml:
import QtQuickimport QtQuick.Layoutsimport Quickshellimport qs.Commonsimport qs.Widgets
Rectangle { id: root
// Plugin API (injected by PluginService) property var pluginApi: null
// Required properties for bar widgets property ShellScreen screen property string widgetId: "" property string section: ""
implicitWidth: row.implicitWidth + Style.marginM * 2 implicitHeight: Style.barHeight
color: Style.capsuleColor radius: Style.radiusM
RowLayout { id: row anchors.centerIn: parent spacing: Style.marginS
NIcon { icon: "heart" color: Color.mPrimary }
NText { text: "My Plugin" color: Color.mOnSurface pointSize: Style.fontSizeS } }}Step 4: Restart Noctalia and Enable Your Plugin
Section titled “Step 4: Restart Noctalia and Enable Your Plugin”After creating these files, restart Noctalia:
# Restart Noctalia (the method depends on your setup)# For systemd:systemctl --user restart noctalia
# Or kill and restart manuallykillall qs && qs -p ~/.config/noctalia/noctalia-shellThen:
- Open Noctalia Settings (Super+comma or click the settings icon)
- Navigate to the Plugins tab
- Find your plugin in the list
- Click Enable
- Your widget should appear in the bar!
Step 5: Add Your Widget to the Bar
Section titled “Step 5: Add Your Widget to the Bar”After enabling the plugin, you need to add it to the bar:
- Go to Settings > Bar tab
- Click on a section (Left/Center/Right)
- Find your plugin widget in the available widgets list
- Add it to your preferred section
What’s Next?
Section titled “What’s Next?”Now that you have a basic plugin working, you can:
-
Add a Panel - Create an overlay panel
-
Bar Widget Development - Advanced bar widget features
-
Plugin API Reference - Complete API documentation
-
Manifest Reference - Full manifest documentation
-
IPC Guide - Respond to external commands
-
Settings UI - Let users configure your plugin
-
Translations - Support multiple languages
Example: Complete Simple Plugin
Section titled “Example: Complete Simple Plugin”Here’s a complete example of a simple plugin that displays a counter:
manifest.json:
{ "id": "counter", "name": "Counter Widget", "version": "1.0.0", "minNoctaliaVersion": "3.6.0", "author": "Your Name", "license": "MIT", "repository": "https://github.com/yourusername/noctalia-plugins", "description": "A simple counter widget", "entryPoints": { "barWidget": "BarWidget.qml" }, "dependencies": { "plugins": [] }, "metadata": { "defaultSettings": { "count": 0 } }}BarWidget.qml:
import QtQuickimport QtQuick.Layoutsimport Quickshellimport qs.Commonsimport qs.Widgetsimport qs.Services.UI
Rectangle { id: root
property var pluginApi: null property ShellScreen screen property string widgetId: "" property string section: ""
property int count: pluginApi?.pluginSettings?.count || 0
implicitWidth: row.implicitWidth + Style.marginM * 2 implicitHeight: Style.barHeight color: Style.capsuleColor radius: Style.radiusM
RowLayout { id: row anchors.centerIn: parent spacing: Style.marginS
NIcon { icon: "numbers" color: Color.mPrimary }
NText { text: root.count.toString() color: Color.mOnSurface pointSize: Style.fontSizeM font.weight: Font.Bold } }
MouseArea { anchors.fill: parent onClicked: { root.count++ pluginApi.pluginSettings.count = root.count pluginApi.saveSettings() ToastService.showNotice("Count: " + root.count) } }
Component.onCompleted: { Logger.i("Counter", "Widget loaded with count:", root.count) }}This creates a counter that:
- Displays a number icon and the current count
- Increments when clicked
- Saves the count to settings
- Shows a toast notification
- Persists across restarts
Hot Reload (Development Mode)
Section titled “Hot Reload (Development Mode)”During plugin development, you can enable hot reload to automatically reload your plugin when you save changes to QML files. This eliminates the need to restart Noctalia after every edit.
Enabling Hot Reload
Section titled “Enabling Hot Reload”Start Noctalia with the NOCTALIA_DEBUG environment variable:
NOCTALIA_DEBUG=1 qs -c noctalia-shellOr if using systemd, create an override:
systemctl --user edit noctaliaAdd:
[Service]Environment="NOCTALIA_DEBUG=1"How It Works
Section titled “How It Works”With debug mode enabled:
- Noctalia watches your plugin’s QML files for changes
- When you save a file, the plugin automatically reloads
- Your changes appear instantly without restarting the shell
- Console output shows reload events for debugging
Usage Tips
Section titled “Usage Tips”- Keep the terminal visible - Watch for QML errors during reload
- Save frequently - Each save triggers a reload so you see changes immediately
- Check for errors - Syntax errors in QML will appear in the console
- State is reset - Plugin state resets on reload (settings persist to disk)
Debugging Tips
Section titled “Debugging Tips”View Logs
Section titled “View Logs”Run Noctalia from the terminal to see logs:
NOCTALIA_DEBUG=1 qs -c noctalia-shellUse Logger in your plugin:
Logger.i("MyPlugin", "Info message")Logger.d("MyPlugin", "Debug message")Logger.w("MyPlugin", "Warning message")Logger.e("MyPlugin", "Error message")Check Plugin Status
Section titled “Check Plugin Status”# View plugin settings filecat ~/.config/noctalia/plugins.json
# View your plugin's manifestcat ~/.config/noctalia/plugins/my-plugin/manifest.json
# View your plugin's settingscat ~/.config/noctalia/plugins/my-plugin/settings.jsonCommon Issues
Section titled “Common Issues”Plugin doesn’t appear in settings:
- Check that
manifest.jsonis valid JSON - Verify the plugin ID matches the directory name
- Restart Noctalia
Widget doesn’t show in bar:
- Make sure you enabled the plugin in Settings > Plugins
- Check that you added the widget in Settings > Bar
- Look for errors in the terminal output
Settings don’t persist:
- Make sure you call
pluginApi.saveSettings()after changing settings - Check file permissions on
~/.config/noctalia/plugins/
Next Steps
Section titled “Next Steps”Continue to learn about:
- Manifest Reference - Complete manifest documentation
- Bar Widgets - Advanced bar widget features
- Plugin API - Full API reference