diff --git a/ro-crate-deposit.js b/ro-crate-deposit.js
index 493f7f76398130c6ac3df2e072f3b34f943fe01b..90d73ea92473dba6ab44c249846327b05547deb3 100644
--- a/ro-crate-deposit.js
+++ b/ro-crate-deposit.js
@@ -1,6 +1,5 @@
 const path = require('path');
 const fs = require('fs-extra');
-const ocfl = require('ocfl');
 const OCFLRepository = require('ocfl').Repository;
 const uuid = require('uuid/v4');
 const argv = require('yargs').argv;
diff --git a/uts-migration.js b/uts-migration.js
new file mode 100644
index 0000000000000000000000000000000000000000..9203e6b65bf45cc3c206be1cda525b366748565f
--- /dev/null
+++ b/uts-migration.js
@@ -0,0 +1,81 @@
+/* Migrate legacy UTS datasets from a directory to an OCFL reposticory */
+
+
+const path = require('path');
+const fs = require('fs-extra');
+const ocfl = require('ocfl');
+const OCFLRepository = require('ocfl').Repository;
+const uuid = require('uuid/v4');
+const argv = require('yargs').argv;
+const ROCrate = require('ro-crate').ROCrate;
+
+
+
+async function connectRepo(repoPath) {
+  const repo = new OCFLRepository();
+  try {
+    const stat = await fs.stat(repoPath);
+    if( stat.isDirectory() ) {
+      await repo.load(repoPath);
+      return repo;
+    } else {
+      console.error(`${repoPath} is not a directory`);
+      process.exit(-1);
+    }
+  } catch(e) {
+    await fs.mkdir(repoPath);
+    await repo.create(repoPath);
+    return repo;
+  }
+}
+
+//  [{"id": " ... ", "doi": "...", "dir": "dir-name of crate", "url": "existing repo URL"}, ...]
+async function addItem(repo, repoName, crateInfo) {
+     // Make a copy of the dataset - assume it has both index.html AND ro-crate stuff in it
+     const tempDir = path.join("temp", path.basename(crateInfo.dir) );
+     const roCrateFile = path.join(tempDir, "ro-crate-metadata.jsonld");
+     const roCrateFileSrc = path.join(crateInfo.dir, "ro-crate-metadata.jsonld");
+     const previewFile = path.join(tempDir, "ro-crate-preview.html");
+     const previewFileSrc = path.join(crateInfo.dir, "ro-crate-preview.html");
+     const indexFile = path.join(tempDir, "index.html");
+
+
+     await fs.copy(crateInfo.dir, tempDir)
+     await fs.remove(roCrateFile);
+     await fs.remove(previewFile);
+     await repo.importNewObjectDir(crateInfo.id, tempDir);
+
+     // Remove legacy index file and add RO-Crate files
+     await fs.remove(indexFile);
+     await fs.copy(roCrateFileSrc, roCrateFile);
+     await fs.copy(previewFileSrc, previewFile);
+
+
+     // Make a crate
+     const jsonld = await fs.readJson(roCrateFile);
+     const crate = new ROCrate(jsonld);
+     crate.index();
+     crate.addIdentifier({name: repoName, identifier: crateInfo.id});
+     await fs.writeJson(roCrateFile, crate.getJson(), {spaces: 2});
+     await repo.importNewObjectDir(crateInfo.id, tempDir);
+     console.log(`Added ${roCrateFile}  metadata with identifier ${crateInfo.id}`);
+     //
+}
+
+
+
+
+async function main() {
+  const repoPath = argv.repo || "ocfl_demo";
+  const repoName = argv.name || "ocfl_demo";
+  const repo = await connectRepo(repoPath);
+  const crateList = await fs.readJson(argv.input);
+  for (let crateInfo of crateList) {
+    await addItem(repo, repoName, crateInfo);
+
+  }
+}
+
+
+main(); 
+
diff --git a/uts_data.json b/uts_data.json
new file mode 100644
index 0000000000000000000000000000000000000000..3f09b235357a8dd8bf74d4cde157991874449eae
--- /dev/null
+++ b/uts_data.json
@@ -0,0 +1,14 @@
+[
+    {
+        "id": "abc", 
+        "doi": "http://doi/1", 
+        "dir": "/Users/124411/working/ro-crate-examples/src/UTS/luckett", 
+        "url": "existing repo URL"
+    },
+    {
+        "id": "abd", 
+        "doi": "http://doi/2", 
+        "dir": "/Users/124411/working/ro-crate-examples/src/samples/sample", 
+        "url": "existing repo URL"
+    }
+]
\ No newline at end of file