diff --git a/src/catalog.js b/src/catalog.js
new file mode 100644
index 0000000000000000000000000000000000000000..adf42a4e5fc80c1cdb64527b5abe22acd2309eae
--- /dev/null
+++ b/src/catalog.js
@@ -0,0 +1,53 @@
+/*
+ * List .json files found in root or first subdirectory level and
+ * return them as a mirador catalog
+ * This code works for webpack dev server and caddy (as file server), and is not expected
+ * to function for other webservers
+ */
+
+export default {
+  get_initial_catalog: function(url = '/data/') {
+    const req_init = {headers: {'Accept': 'application/json'}};
+    return fetch(url, req_init)
+      // fetch root ressources & try to parse it to json
+      .then(response => {
+        if (!response.ok)
+          throw new Error(`failed to list manifests from '${document.location}/data', http response code: ${reponse.status}`);
+        return response.json();
+      })
+      .then(async (response_json) => {
+        let items = [['/', response_json]];
+        // handle caddy response, which is like:
+        // [ {name: file1, props: ...}, {name: file2, props: ...}, {name: dir1, props: ...} ]
+        if (typeof(response_json[0].name) != 'undefined')
+          response_json = response_json.map(e => e.name.replace(/\/$/, ''));
+
+        // try to GET on "folders", parse responses to json,
+        // and return them as an array [folder_name, json_responses_array]
+        // (assuming files not ending in .json are folder; errors are ignored)
+        let res = await Promise.allSettled(response_json
+          .filter(e => !e.endsWith('.json'))
+          .map(folder => fetch(url + folder, req_init)
+            .then(e => e.json())
+            .then(e => [folder, e])
+          )
+        );
+
+        // extract only successful responses values
+        items = items.concat(res
+          .filter(p => p.status === "fulfilled")
+          .map(p => p.value));
+
+        // return each entry ending in .json with current location,
+        // and folder if needed
+        return items
+          .flatMap(([folder, entries]) => entries
+            .map(e => typeof(e.name) != 'undefined' ? e.name : e) // handling caddy response
+            .filter(e => e.endsWith('.json'))
+            .map(e => {
+              return {'manifestId': document.location + 'data' + (folder == '/' ? '/' : `/${folder}/`) + e};
+            })
+          );
+      });
+  }
+}
diff --git a/src/index.js b/src/index.js
index f0b501b55d4ef7ada83a58d2d5f18b7559bf9ef4..76e532c2468040220e7302ee55818c147f439920 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,5 +1,6 @@
 import Mirador from 'mirador/dist/es/src/index';
-
+import LocalCatalog from './catalog.js';
+import * as actions from 'mirador/dist/es/src/state/actions';
 
 const config = {
   id: 'demo',
@@ -16,5 +17,16 @@ const config = {
   ]
 }
 
-Mirador.viewer(config, [
-]);
+let viewer = Mirador.viewer(config, []);
+var store = viewer.store;
+console.info('store: ', store);
+
+LocalCatalog.get_initial_catalog()
+  .then(catalog => {
+    console.debug('loading local catalog: ', catalog);
+
+    catalog.forEach(manifest => 
+      // setTimeout avoid UI freeze
+      setTimeout(() => store.dispatch(actions.addResource(manifest.manifestId)), 0)
+    );
+  })