SWIRL for Backstage
What it does
SWIRL for Backstage replaces the search engine behind the Backstage search plugin. Backstage keeps its collators, its search page, and its permission filtering. SWIRL supplies the index, the relevance, and results from systems that Backstage does not index.
Two things ship:
- The npm package
@swirl-search/backstage-plugin-search-backend-module-swirl, a search backend module. - The container image
swirlai/swirl-backstage, which is SWIRL Community with an embedded Tantivy index.
The two lanes
Every query runs over two lanes and both are ranked together.
- Indexed lane. Every document a Backstage collator produces is written to a Tantivy index inside SWIRL. Catalog entities and TechDocs pages are the usual two. Queries are answered with BM25 relevance, n-gram matching on titles, and optional typo tolerance.
- Federated lane. SWIRL queries connected sources live, once per query. GitHub and Confluence are the sources in this release. Those results arrive under the Backstage document type
swirl-federatedand appear in the same result list.
The engine module writes documents to SWIRL as the collators produce them, and asks SWIRL for results at query time. It forwards the Backstage plugin token unchanged, so SWIRL knows which user asked. Page 0 of a result set federates. Later pages are database reads in SWIRL, which keeps Backstage's permission paging loop cheap.
See it work
Two minutes and fifty five seconds, with narration. A stock Backstage, the same queries before and after, then GitHub results arriving in the same ranked list. Every step is on the install page. Also on YouTube: the full demo and the 30 second cut.
SWIRL for Backstage, end to end: install, the relevance difference, and the federated lane.
What it does not do
- It does not replace collators. The catalog and TechDocs collators run on their normal schedule. Only the storage and the relevance move to SWIRL.
- It does not index external sources. GitHub and Confluence are queried live. Nothing from them is written to the Backstage index, and SWIRL stores no copy of their content.
- It does not change the Backstage search page. Catalog and TechDocs results render through their existing renderers. Federated results render through the default list item.
- It does not filter federated results through Backstage permissions. Backstage can only filter what it indexed. See Security.
- It is not a cluster. One container, one volume, no JVM, no separate database for SWIRL.
Editions
OAuth2 is the dividing line between the two editions. SWIRL Community authenticates to a federated source with one service account, shared by every portal user. SWIRL Enterprise adds sources that authenticate per user with OAuth2.
| Capability | Community | Enterprise |
|---|---|---|
| Tantivy index for catalog, TechDocs, and any other collator | Yes | Yes |
| BM25 relevance, n-gram titles, typo tolerance, attribute filters | Yes | Yes |
| Federated GitHub and Confluence with a service account | Yes | Yes |
| Mandatory scope restriction on federated sources | Yes | Yes |
| Backstage permission filtering on indexed results | Yes | Yes |
| OAuth2 sources and OAuth2-only sources | No | Yes |
| Per-user identity passthrough to a federated source | No | Yes |
| Semantic cache and cross-source deduplication | No | Yes |
| License | Apache 2.0, free | SWIRL for Backstage SKU, licensed for use inside Backstage |
In SWIRL Community every portal user sees whatever the federated source's service account can read. Read Security before you activate GitHub or Confluence.
Measured numbers
These are measurements from the first build, not targets. They were taken on 2026-09-03 on macOS on arm64.
| Measurement | Value |
|---|---|
| Container resident memory, idle | about 2.5 GiB |
| Container resident memory, 5,071 documents indexed | about 2.6 GiB |
| Image size on disk | about 7 GB |
| Tantivy index size at 50,000 entities | 34 MB |
| Indexing throughput at 50,000 entities | about 18,600 documents per second |
| Mean query time at 50,000 entities, Tantivy layer | 0.255 ms |
| Time from container start to healthy | about 15 seconds |
| Time from Backstage backend start to the first live index | 3.2 seconds |
Memory and image size are dominated by the machine learning libraries SWIRL imports, not by the index. Tantivy accounts for about 150 MB. A slimmer image profile is planned. Until it ships, these are the numbers to plan against, and the Kubernetes manifest requests 768 MiB with a 2 GiB limit.
Relevance results
Nine relevance cases were run against the Backstage example catalog plus 5,000 synthetic entities, 5,071 documents in total. All nine passed on Tantivy. The same cases were run against a live Backstage using the default Lunr engine on the 71 example documents.
techreturnstech-radarfirst on Tantivy, with no team-only entity in the top five. Lunr returns 38 results and placesteam-athroughteam-dat ranks 8 to 11.storereturnspetstorefirst on Tantivy. Lunr returns seven results and none of them ispetstore.mesreturns nothing on Tantivy. Lunr returns 14 results, none containing the string, led by a person entity.foo-bar.comreturns the entity at rank one on Tantivy. On a catalog with no such entity Lunr returns 59 results, the first twelve of them user entities.abacfindsabacus,petsotrefindspetstorewith typo tolerance on, and attribute filters return only matching documents.
The Postgres engine was not measured in that run. Only Lunr was.
Where to go next
- Install: compose, Kubernetes, the npm package, and the verify steps.
- Configuration reference: every app-config key and every SWIRL environment variable.
- Security: the shared credential model and the scope restriction.
- GitHub and Confluence: one page per source.
- Troubleshooting and FAQ.