diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..3f202e558b408ef94f024c5150845c4a03119180
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,11 @@
+libs = sqlite3 uuid
+CFLAGS = -Wall -pedantic -std=c2x -fPIC \
+		 -ggdb \
+		 $(shell pkg-config --cflags $(libs))
+LDLIBS = $(shell pkg-config --libs $(libs))
+
+C_FILES = sqlite-uuid.c
+O_FILES = $(C_FILES:%.c=%.o)
+
+sqlite-uuid.so: $(O_FILES)
+	$(CC) -shared -o $@ $^ $(LDLIBS)
diff --git a/sqlite-uuid.c b/sqlite-uuid.c
new file mode 100644
index 0000000000000000000000000000000000000000..b9a66969b16e0d1d8c67a0e58169bbcd7f385dc7
--- /dev/null
+++ b/sqlite-uuid.c
@@ -0,0 +1,35 @@
+#include <sqlite3ext.h>
+SQLITE_EXTENSION_INIT1
+#include <uuid.h>
+
+static void sqlite_uuid(sqlite3_context *context, int argc, sqlite3_value **argv) {
+	uuid_t uuid;
+	uuid_generate_random(uuid);
+
+	char str[37];
+	uuid_unparse(uuid, &str[0]);
+
+	sqlite3_result_text(context, str, 37, SQLITE_TRANSIENT);
+
+	uuid_clear(uuid);
+}
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int sqlite3_extension_init (
+	sqlite3 *db,
+	char **pzErrMsg,
+	const sqlite3_api_routines *pApi
+) {
+	int rc = SQLITE_OK;
+	SQLITE_EXTENSION_INIT2(pApi);
+
+	(void) pzErrMsg;
+
+	rc = sqlite3_create_function(db, "uuid", 0,
+	   SQLITE_UTF8|SQLITE_INNOCUOUS,
+	   0, sqlite_uuid, 0, 0);
+
+	return rc;
+}
diff --git a/test.sql b/test.sql
new file mode 100644
index 0000000000000000000000000000000000000000..da304544a4775cde5eb905d03f9e330697a123d4
--- /dev/null
+++ b/test.sql
@@ -0,0 +1,2 @@
+.load sqlite-uuid
+SELECT uuid();