diff --git a/deploy/plugins/index.js b/deploy/plugins/index.js
index 929f19499786e69b7dc1461a27ae96972e32b8a0..8d6bee52dadaf45913c133479a42142b3c2a4a3e 100644
--- a/deploy/plugins/index.js
+++ b/deploy/plugins/index.js
@@ -7,6 +7,16 @@ const express = require('express')
 const lruStore = require('../lruStore')
 const got = require('got')
 const router = express.Router()
+const DEV_PLUGINS = (() => {
+  try {
+    return JSON.parse(
+      process.env.DEV_PLUGINS || `[]`
+    )
+  } catch (e) {
+    console.warn(`Parsing DEV_PLUGINS failed: ${e}`)
+    return []
+  }
+})()
 const PLUGIN_URLS = (process.env.PLUGIN_URLS && process.env.PLUGIN_URLS.split(';')) || []
 const STAGING_PLUGIN_URLS = (process.env.STAGING_PLUGIN_URLS && process.env.STAGING_PLUGIN_URLS.split(';')) || []
 
@@ -44,7 +54,7 @@ router.get('/manifests', async (_req, res) => {
   }))
 
   res.status(200).json(
-    allManifests.filter(v => !!v)
+    [...DEV_PLUGINS, ...allManifests.filter(v => !!v)]
   )
 })
 
diff --git a/docs/releases/v2.6.0.md b/docs/releases/v2.6.0.md
index 72f97e1392db3f20dde8b5c483e105a72ef0a8a6..95fd0880cd9a39f3cf23c3897ef34944f315ce6f 100644
--- a/docs/releases/v2.6.0.md
+++ b/docs/releases/v2.6.0.md
@@ -1,4 +1,8 @@
-# v2.5.0
+# v2.6.0
+
+## New features
+
+- add the capability of add 3rd party plugins (experimental)
 
 ## Under the hood stuff
 
diff --git a/src/atlasComponents/userAnnotations/tools/type.spec.ts b/src/atlasComponents/userAnnotations/tools/type.spec.ts
index f4b28738913465c7eda8ee898f28fdc724dbf016..599f20eabb8289dc975b501c876418df055e7d57 100644
--- a/src/atlasComponents/userAnnotations/tools/type.spec.ts
+++ b/src/atlasComponents/userAnnotations/tools/type.spec.ts
@@ -2,6 +2,7 @@ import { Subject, Subscription } from "rxjs"
 import { AbsToolClass, IAnnotationEvents, IAnnotationGeometry, TAnnotationEvent } from "./type"
 
 class TmpCls extends IAnnotationGeometry{
+  annotationType: 'tmpl-cls'
   getNgAnnotationIds(){
     return []
   }
@@ -110,6 +111,7 @@ describe('> types.ts', () => {
 
     describe('> updateSignal$', () => {
       class TmpCls extends IAnnotationGeometry{
+        annotationType = 'tmp-cls'
         getNgAnnotationIds(){
           return []
         }
diff --git a/src/plugin/atlasViewer.pluginService.service.ts b/src/plugin/atlasViewer.pluginService.service.ts
index 1c83a6d28b92622728c9653cf0562846cd28e2cb..668027764cf639fe3be327119a12fb4140352f08 100644
--- a/src/plugin/atlasViewer.pluginService.service.ts
+++ b/src/plugin/atlasViewer.pluginService.service.ts
@@ -375,6 +375,18 @@ export class PluginServices {
 
     return handler
   }
+
+  public async addPluginViaManifestUrl(manifestUrl: string){
+    try {
+      const json = await this.fetch(manifestUrl)
+      this.fetchedPluginManifests = [
+        ...this.fetchedPluginManifests,
+        json
+      ]
+    } catch (e) {
+      throw new Error(e.statusText)
+    }
+  }
 }
 
 export interface IPluginManifest {
diff --git a/src/plugin/pluginBanner/pluginBanner.component.ts b/src/plugin/pluginBanner/pluginBanner.component.ts
index 59de1360d44b7db00fc1f9e5567371debf03b650..069be28e672895730be63fb7bdd41fb657c883e7 100644
--- a/src/plugin/pluginBanner/pluginBanner.component.ts
+++ b/src/plugin/pluginBanner/pluginBanner.component.ts
@@ -1,6 +1,8 @@
 import { Component, ViewChild, TemplateRef } from "@angular/core";
 import { IPluginManifest, PluginServices } from "../atlasViewer.pluginService.service";
 import { MatDialog } from "@angular/material/dialog";
+import { environment } from 'src/environments/environment';
+import { MatSnackBar } from "@angular/material/snack-bar";
 
 @Component({
   selector : 'plugin-banner',
@@ -12,12 +14,15 @@ import { MatDialog } from "@angular/material/dialog";
 
 export class PluginBannerUI {
 
+  EXPERIMENTAL_FEATURE_FLAG = environment.EXPERIMENTAL_FEATURE_FLAG
+
   @ViewChild('pluginInfoTmpl', { read: TemplateRef })
   private pluginInfoTmpl: TemplateRef<any>
 
   constructor(
     public pluginServices: PluginServices,
     private matDialog: MatDialog,
+    private matSnackbar: MatSnackBar,
   ) {
   }
 
@@ -34,4 +39,24 @@ export class PluginBannerUI {
       }
     )
   }
+
+  public showTmpl(tmpl: TemplateRef<any>){
+    this.matDialog.open(tmpl, {
+      minWidth: '60vw'
+    })
+  }
+
+  public loadingThirdpartyPlugin = false
+
+  public async addThirdPartyPlugin(manifestUrl: string) {
+    this.loadingThirdpartyPlugin = true
+    try {
+      await this.pluginServices.addPluginViaManifestUrl(manifestUrl)
+      this.loadingThirdpartyPlugin = false
+      this.matSnackbar.open(`Adding plugin successful`)
+    } catch (e) {
+      this.loadingThirdpartyPlugin = false
+      this.matSnackbar.open(`Error adding plugin: ${e.toString()}`)
+    }
+  }
 }
diff --git a/src/plugin/pluginBanner/pluginBanner.template.html b/src/plugin/pluginBanner/pluginBanner.template.html
index 6216ee8247a5ac011f3ec41acf7f58cb7e52d0d3..3e452612ebef6347181b825c02c22c5ba2ce8c74 100644
--- a/src/plugin/pluginBanner/pluginBanner.template.html
+++ b/src/plugin/pluginBanner/pluginBanner.template.html
@@ -15,8 +15,46 @@
       {{ plugin.displayName ? plugin.displayName : plugin.name }}
     </span>
   </button>
+
+  <button mat-menu-item *ngIf="EXPERIMENTAL_FEATURE_FLAG"
+    (click)="showTmpl(thirdPartyPluginTmpl)">
+    <span>
+      Add third party plugin
+    </span>
+  </button>
 </mat-action-list>
 
+<ng-template #thirdPartyPluginTmpl>
+  <h2 mat-dialog-title>
+    Add thirdparty plugin
+  </h2>
+
+  <mat-dialog-content>
+    <form>
+      <mat-form-field class="d-block">
+        <mat-label>
+          manifest.json URL
+        </mat-label>
+        <input type="text" matInput placeholder="https://example.com/manifest.json" #urlInput>
+      </mat-form-field>
+    </form>
+  </mat-dialog-content>
+
+  <mat-dialog-actions align="end">
+    <button (click)="addThirdPartyPlugin(urlInput.value)"
+      mat-raised-button
+      [disabled]="loadingThirdpartyPlugin"
+      color="primary">
+      Load
+    </button>
+    <button mat-dialog-close
+      mat-button>
+      cancel
+    </button>
+  </mat-dialog-actions>
+
+</ng-template>
+
 <ng-template #pluginInfoTmpl let-manifest>
   <h1 mat-dialog-title>
     About {{ manifest.displayName || manifest.name }}