diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..20671ec
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+repos.edn
+.nrepl-port
diff --git a/deps.edn b/deps.edn
new file mode 100644
index 0000000..0750e80
--- /dev/null
+++ b/deps.edn
@@ -0,0 +1,2 @@
+{:deps {metosin/jsonista {:mvn/version "0.3.5"}}
+ :aliases {:csv-export {:main-opts ["-m" "metosin.repos"]}}}
diff --git a/src/metosin/repos.clj b/src/metosin/repos.clj
new file mode 100644
index 0000000..b474612
--- /dev/null
+++ b/src/metosin/repos.clj
@@ -0,0 +1,53 @@
+(ns metosin.repos
+  (:require [jsonista.core :as json]
+            [clojure.java.io :as io]
+            [clojure.edn :as edn]
+            [clojure.pprint :refer [pprint]]
+            [clojure.string :as str]))
+
+(defn repos
+  ([]
+   (repos "https://api.github.com/orgs/Metosin/repos?type=public"))
+  ([url]
+   (let [u (java.net.URL. url)
+         c (.openConnection u)
+         links (-> (.getHeaderField c "Link")
+                   (str/split #",")
+                   (->> (map (fn [x]
+                               (let [[_ url rel] (re-matches #"<(.*)>; rel=\"(.*)\"" (str/trim x))]
+                                 [rel url])))
+                        (into {})))
+         data (with-open [is (.getInputStream c)]
+                (json/read-value is json/keyword-keys-object-mapper))]
+     (if-let [x (get links "next")]
+       (into data (repos x))
+       data))))
+
+(defn update-github-data []
+  (let [data (repos)]
+    (spit (io/file "repos.edn") (with-out-str (pprint data)))))
+
+(def all-repos (edn/read-string (slurp (io/file "repos.edn"))))
+
+(comment
+  (update-github-data)
+  (first all-repos))
+
+(def topic->stage
+  {"metosin-experimental" :experimental
+   "metosin-active-development" :active-development
+   "metosin-stable" :stable
+   "metosin-deprecated" :deprecated})
+
+(defn csv-export []
+  (doseq [{:keys [topics archived open_issues_count] :as repo} all-repos]
+    (let [stages (keep topic->stage topics)]
+      (println (str (:name repo) ","
+                    archived ","
+                    (if (seq stages)
+                      (str/join " " (map name stages))
+                      "unknown") ","
+                    open_issues_count)))))
+
+(defn -main [& _]
+  (csv-export))