Browse API 1 documentation
GroveAPI 1preview

Choose an extension type

Decide between a visible Sprig, composer utility, or headless Root.

Mango 3.1+View Markdown

Start with what the user should see. Grove has one package format, but its presentation determines how people open and use the extension.

What you are building Choose Typical result
A dashboard, browser, game, or other persistent custom interface beside a conversation Visible Sprig using channelPane, optionally window The extension renders its own HTML UI.
A bot console or dashboard that owns several joined channels on one network Network tab Sprig using exclusive tab + server scope Mango runs one visible instance for that IRC session.
A picker or generator that briefly opens from the message composer Composer Sprig using composer It returns text to the draft with grove.composer.complete(...).
Slash commands, native cards, badges, filters, member actions, or an upload provider Headless Root using headless It has no web UI of its own and contributes native behavior to Mango.

A settings page is optional configuration UI, not a fourth extension type. Any Sprig or Root may declare settings when it needs preferences or credentials.

Choose the surface first

Visible Sprig

Use a visible Sprig when the extension itself is something the user looks at or interacts with for more than one quick action.

json
"presentation": {
  "surfaces": ["channelPane", "window"],
  "defaultSurface": "channelPane"
}

Starting the Sprig from a conversation binds it to that conversation. window changes where the same content appears; it does not widen what IRC data the extension may access.

Good fits include a channel activity dashboard, a poll editor, a shared-game interface, or a tool that needs its own navigation.

Network tab Sprig

Use a server-scoped tab when one visible runtime coordinates several joined channels on the same IRC connection:

json
"presentation": {
  "surfaces": ["tab"],
  "defaultSurface": "tab",
  "scope": "server"
}

tab is exclusive. Mango runs one instance per package and network, and reopening it selects the existing tab. Request channel.read to receive live messages plus the joined-channel roster, and network.send only when the extension must explicitly reply into those confirmed joined channels.

Composer Sprig

Use a composer Sprig for a focused choose-or-generate flow that ends by inserting text into Mango’s draft.

json
"presentation": {
  "surfaces": ["composer"],
  "defaultSurface": "composer"
}

composer must be the only surface. It opens only after an explicit user action, receives no IRC message stream or implicit send target, and cannot autostart. Finish with grove.composer.complete(text) so the user can review and send the result.

Good fits include GIF and emoji pickers, canned-response browsers, link builders, and local text transforms.

Headless Root

Use a Root when Mango should provide the visible UI, or when the extension reacts without presenting a pane.

json
"presentation": {
  "surfaces": ["headless"]
}

A Root can register slash commands and native cards, publish status badges, add member-menu actions, filter messages, or provide an upload destination. Request only the capabilities used by those integrations.

Good fits include weather commands, message formatters, encryption filters, moderation helpers, and upload providers.

Then choose the scope

Surface and scope are separate decisions. A surface answers where is it visible? Scope answers which Mango or IRC context is it bound to?

Required context Scope Notes
One channel or direct message Omit presentation.scope Mango binds the instance to the conversation from which it starts.
One IRC connection "scope": "server" One instance for that network session. Appropriate for a network tab, connection-wide commands, or filters.
The Mango application, without IRC message access "scope": "application" Shared configuration and passive integrations such as an upload provider available across networks.

For example, a connection-wide Root declares:

json
"presentation": {
  "surfaces": ["headless"],
  "scope": "server"
}

Application scope is intentionally not ambient access to every network. It has no IRC message, command, filter, presence, or implicit send route. Use it when a host integration should be configured once and does not need to observe IRC traffic.

Match capabilities to the feature

Capabilities describe the native operations the extension needs; hostPermissions separately lists external HTTPS or WSS origins it may contact.

Feature Typical capability
Read the bound conversation channel.read or query.read
Read all live joined channels from server scope channel.read
Send to the bound conversation channel.send or query.send
Create and select a new private conversation while sending query.send and query.open
Send to an explicit confirmed joined channel from server scope network.send
Register slash commands and native cards commands.register
Open a service profile from a native member action ui.member-actions and ui.web-pane, plus matching hostPermissions
Publish native status badges statusbar
Filter displayed or outgoing messages messages.filter.inbound or messages.filter.outbound
Contribute an upload destination uploads.provide
Upload one file produced by a composer utility through Mango uploads.use
Open a system OAuth Authorization Code and PKCE flow oauth.authorize
Call a non-CORS HTTPS API through bounded native transport network.request plus matching hostPermissions
Persist ordinary web data storage
Store credentials in Keychain storage.secure

See Capabilities before finalizing the manifest. A capability must be both declared and accepted by the user, and Mango checks the grant again for every bridge call.

Still unsure?

Choose the smallest shape that completes the user action:

  1. If the user needs to browse or manipulate a custom interface, start with a visible Sprig.
  2. If the interface exists only to produce draft text, use a composer Sprig.
  3. If native cards, commands, filters, badges, or uploads are enough, use a headless Root.
  4. Add a settings page only when configuration is necessary.

Continue with the Starter recipes to see each shape as a complete two-file package.