diff --git a/README b/README
index 8ec148a..92c04ec 100644
--- a/README
+++ b/README
@@ -7,9 +7,8 @@ to be uploaded to a web server, or simply viewed in the browser. Tumblr and
 Twitter (through nitter) sources are supported.
 
 | Usage
-Rssssing only works with the Bun[1] runtime 
 
-- Run `bun run setup`, `npm run setup`, etc.
+- Run `yarn run setup`, `npm run setup`, etc.
 - Add usernames and such to the "feeds" array in config.js
 - `bun .`
 - Open `out/index.html` in a browser. Enjoy :)
diff --git a/index.js b/index.js
index c49433d..270a31b 100644
--- a/index.js
+++ b/index.js
@@ -1,12 +1,34 @@
-const fetch = require('node-fetch')
-const config = require('./config.js')
-const Path = require('path')
+// const fetch = require('node-fetch')
+// const config = require('./config.js')
+// const Path = require('path')
+// const { writeFile } = require('fs/promises')
 
-let cache = require('./cache.json')
-const { JSDOM } = require('jsdom')
+// let cache = require('./cache.json')
+// const { JSDOM } = require('jsdom')
 
+import fetch from "node-fetch"
+import Path from "path"
+import FS from "fs/promises"
+import { JSDOM } from "jsdom"
+
+import config from "./config.js"
+
+let cache = await FS.readFile('./cache.json', { encoding: 'utf-8' })
+  .then(json => JSON.parse(json) )
 let waitingList = new Map()
 
+const write = async (path, content) => {
+  let dir = Path.dirname(path)
+  
+  try {
+    await FS.access(dir)
+  } catch(e) {
+    await FS.mkdir(dir, { recursive: true })
+  }
+
+  return await FS.writeFile(path, content)
+} 
+
 const handleNitterUser = async user => {
   let data
   let index = 0
@@ -78,7 +100,7 @@ const fetchRss = async (hostname, path) => {
     waitingList.set(hostname, 0)
   }
 
-  return await fetch(new URL(path, 'https://' + hostname))
+  return await fetch(new URL(path, 'https://' + hostname) )
     .then(response => {
       waitingList.set(hostname, config.courtesyWait)
       return response.text()
@@ -150,11 +172,9 @@ const printFeed = async (sources, directory, header, viewOptions) => {
   let tooLongAgo = viewOptions.tooLongAgo ?
     (Date.now() - (Date.now() % oneDay)) - oneDay * viewOptions.tooLongAgo :
     0
-  let missingSources = 0
 
   for(let source of sources) {
     if(source == undefined) {
-      missingSources++
       continue
     }
 
@@ -166,10 +186,6 @@ const printFeed = async (sources, directory, header, viewOptions) => {
 
   feed = feed.sort((a, b) => a.date < b.date)
 
-  if(missingSources) {
-    console.log('Missing ' + missingSources + ' feeds!')
-  }
-
   // Render
 
   let pages = []
@@ -184,7 +200,7 @@ const printFeed = async (sources, directory, header, viewOptions) => {
 
   const writePage = (index, content) =>
     promises.push(
-      Bun.write(Path.join(directory, index == 0 ? 'index' : index) + '.html', content)
+      write(Path.join(directory, index == 0 ? 'index' : index.toString() ) + '.html', content)
     )
 
   for(let i = 0; i < pages.length; i++) {
@@ -194,7 +210,7 @@ const printFeed = async (sources, directory, header, viewOptions) => {
       `<a href="data:text/html,">end</a>` :
       `<a href="${nextPage}.html">next</a>`
 
-    writePage(i, renderPage(`Page ${i + 1}`, pages[i], header, link))
+    writePage(i, renderPage(`Page ${i + 1}`, pages[i], header, link) )
   }
 
   if(pages.length == 0) {
@@ -213,9 +229,9 @@ const renderPage = (title, posts, header, footer) => {
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <style>
   body {
-    width: 100vw;
     max-width: 640px;
-    float: right;
+    margin: 0 0 0 auto;
+    padding: 8px;
     font-family: sans-serif;
   }
 
@@ -279,23 +295,27 @@ const renderImage = image => `\
 <a href="${image}"><img src="${image}" loading="lazy"></img></a>`
 
 const main = async () => {
+  let promises = []
   let feeds = []
-  let allSources = []
+  let sources = []
+
+  const wait = promise =>
+    promises.push(promise)
 
   for(let feedName in config.feeds) {
     let feed = config.feeds[feedName]
-    let sources = []
+    let feedSources = []
 
-    const subscribe = (sourcePromise, type, name) =>
-      sourcePromise
+    const subscribe = (postPromise, type, name) =>
+      postPromise
         .catch(error => console.error(error) )
-        .then(source => {
-          sources.push(source)
-          allSources.push({
+        .then(posts => {
+          feedSources.push(posts)
+          sources.push({
             type,
             name,
             link: Path.join(type, name),
-            source
+            posts
           })
         })
 
@@ -304,7 +324,7 @@ const main = async () => {
         await subscribe(handleNitterUser(user), 'nitter', user)
       }
       console.log('Caching sources...')
-      Bun.write('cache.json', JSON.stringify(cache, null, 2))
+      wait(write('cache.json', JSON.stringify(cache, null, 2) ) )
     }
 
     if(feed.tumblr) {
@@ -319,19 +339,27 @@ const main = async () => {
       name: feedName,
       main: feed.main,
       view: feed.view,
-      sources,
+      sources: feedSources,
       link
     })
   }
 
-  const buildFeedNav = depth => {
-    const buildLink = (page, name = page.link) => {
-      let link = '../'.repeat(depth) + page.link
+  const buildNav = depth => {
+    const root = '../'.repeat(depth)
 
-      if(config.linkToIndex)
-        link += '/index.html'
+    const buildLink = link =>
+      config.linkToIndex ? link + 'index.html' : link
 
-      return `<li><a href="${link}">${name}</a></li>`
+    const renderEntry = (page, name = page.link) => {
+      let link = buildLink(root + page.link + '/')
+      let extra = ''
+
+      if(page.posts === undefined) {
+        console.log(page)
+        extra += ' (missing)'
+      }
+
+      return `<li><a href="${link}">${name}</a>${extra}</li>`
     }
 
     return `\
@@ -341,14 +369,14 @@ const main = async () => {
 <section>
 <ul>
 
-${buildLink({ link: '' }, 'main')}
-${feeds.filter(feed => !feed.main).map(feed => buildLink(feed)).join('\n')}
+<li><a href="${buildLink(root)}">main</a></li>
+${feeds.filter(feed => !feed.main).map(feed => renderEntry(feed)).join('\n')}
 
 </ul>
 <hr>
 <ul>
 
-${allSources.map(source => buildLink(source)).join('\n')}
+${sources.map(source => renderEntry(source)).join('\n')}
 
 </ul>
 </section>
@@ -357,17 +385,21 @@ ${allSources.map(source => buildLink(source)).join('\n')}
 <hr>`
   }
 
-  let promises = []
+  let navs = [
+    buildNav(0),
+    buildNav(1),
+    buildNav(2)
+  ]
 
   console.log('Writing...')
-  for(let source of allSources) {
-    promises.push(
-      printFeed([ source.source ], Path.join('out', source.link), buildFeedNav(2), config.sourceView)
+  for(let source of sources) {
+    wait(
+      printFeed([ source.posts ], Path.join('out', source.link), navs[2], config.sourceView)
     )
   }
   for(let feed of feeds) {
-    promises.push(
-      printFeed(feed.sources, Path.join('out', feed.link), buildFeedNav(feed.main ? 0 : 1), feed.view)
+    wait(
+      printFeed(feed.sources, Path.join('out', feed.link), navs[feed.main ? 0 : 1], feed.view)
     )
   }
 
diff --git a/package.json b/package.json
index 77e6624..0fd18bf 100644
--- a/package.json
+++ b/package.json
@@ -11,5 +11,6 @@
   "dependencies": {
     "jsdom": "^22.1.0",
     "node-fetch": "^3.3.1"
-  }
+  },
+  "type": "module"
 }