diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000000000000000000000000000000000000..67130f76d0ca6246b73d6daccbcf101387dd5220
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,11 @@
+{
+    "extends": "standard",
+    "installedESLint": true,
+    "plugins": [
+        "standard",
+        "promise"
+    ],
+    "rules": {
+        "semi": "always"
+    }
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..a6fb97658686cea8079026fb746ee7f1b88406ae
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+    "eslint.enable": true
+}
\ No newline at end of file
diff --git a/index.js b/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..d598a778ab9740263ce18081cf43730ea85d5683
--- /dev/null
+++ b/index.js
@@ -0,0 +1,5 @@
+module.exports = {
+    getFile: require('./lib/getfile'),
+    scanner: require('./lib/scanner'),
+    refreshclam: require('./lib/refreshclam')
+}
\ No newline at end of file
diff --git a/lib/getfile.js b/lib/getfile.js
new file mode 100644
index 0000000000000000000000000000000000000000..a10472a4001abade4dff807924c5e083306cb6eb
--- /dev/null
+++ b/lib/getfile.js
@@ -0,0 +1,11 @@
+module.exports = function getFile(S3, key) {
+  return new Promise((resolve, reject) => {
+    S3.getObject({
+      Bucket: `${process.env.SERVICE}-filestore-${process.env.STAGE}-1`,
+      Key: key
+    }, (err, file) => {
+      if (err) return void reject(err);
+      resolve(file);
+    });
+  });
+}
\ No newline at end of file
diff --git a/lib/refreshclam.js b/lib/refreshclam.js
new file mode 100644
index 0000000000000000000000000000000000000000..d87d5118f19ab94964f61891e2e5e85ceb908528
--- /dev/null
+++ b/lib/refreshclam.js
@@ -0,0 +1,15 @@
+const exec = require('child_process').exec;
+const debug = require("debug")("scanner");
+
+module.exports = function refresh() {
+  return new Promise((resolve, reject) => {
+    debug('Updating virus database')
+    const proc = exec('freshclam', [], {stdio: 'inherit'});
+    proc.on('error', reject);
+    proc.on('exit', code => {
+      if (code !== 0) return void reject(new Error(`Clamscan exited with code ${code}`));
+      debug('Finished updating');
+      resolve();
+    })
+  });
+}
\ No newline at end of file
diff --git a/lib/scanner.js b/lib/scanner.js
new file mode 100644
index 0000000000000000000000000000000000000000..3128696078d63b0b30f8aa7e904f44e1bffb9f68
--- /dev/null
+++ b/lib/scanner.js
@@ -0,0 +1,22 @@
+const clam = require('clamscan')();
+const fs = require('fs');
+const path = require('path');
+const getFile = require('./getfile');
+
+module.exports = function scanFile(notif, S3) {
+  return new Promise((resolve, reject) => {
+    const key = notif.Records[0].s3.object.key;
+    getFile(S3, key).then(file => {
+      const filepath = path.resolve(path.join(__dirname, '/files/', key));
+      fs.writeFile(filepath, file.body, (err) => {
+        if (err) return void reject(err);
+        clam.is_infected(filepath, (err, _, is_infected) => {
+          fs.unlink(filepath, (unlinkErr) => {
+            if (err || unlinkErr) return void reject(err || unlinkErr);
+            resolve({infected: is_infected});
+          });
+        });
+      });
+    }, reject);
+  });
+}
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..030bd75b8209bf7b8f8429f47f7b19ff147bedb1
--- /dev/null
+++ b/package.json
@@ -0,0 +1,31 @@
+{
+  "name": "whats-a-virus",
+  "version": "0.0.1",
+  "description": "Whats this, a virus? Scanner built for whats-th.is file uploader.",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/whats-this/scanner.git"
+  },
+  "keywords": [
+    "av",
+    "antivirus",
+    "clamscan",
+    "clamav"
+  ],
+  "author": "aurieh",
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/whats-this/scanner/issues"
+  },
+  "homepage": "https://github.com/whats-this/scanner#readme",
+  "devDependencies": {
+    "eslint": "^3.12.1",
+    "eslint-config-standard": "^6.2.1",
+    "eslint-plugin-promise": "^3.4.0",
+    "eslint-plugin-standard": "^2.0.1"
+  }
+}