diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000000000000000000000000000000000000..1bfea57ad3cd66ce4bd8b62ae850252ae0ad3044
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,17 @@
+@make_variables@
+
+VPATH=@srcdir@
+MODNAME=Sass
+MODDIR=Tools.pmod/
+MODULE_PMOD_IN=module.pmod.in
+MODULE_WRAPPER_PREFIX=_
+MODULE_LDFLAGS=@LDFLAGS@ @LIBS@ @CMOD_LIBS@
+MODULE_CFLAGS=@CMOD_CFLAGS@
+OBJS=sass.o
+
+@dynamic_module_makefile@
+
+sass.o : $(SRCDIR)/sass.c
+
+@dependencies@
+
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000000000000000000000000000000000000..2ac0a2eef30eca538b862f3c11233bb23f4910c4
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,13 @@
+AC_INIT(sass.cmod)
+AC_MODULE_INIT()
+
+CMOD_LIBS="-lsass"
+CMOD_CFLAGS=""
+
+AC_SUBST(CMOD_CFLAGS)
+AC_SUBST(CMOD_LIBS)
+
+AC_HAVE_HEADERS(sass.h)
+AC_CHECK_HEADERS(sass.h)
+
+AC_OUTPUT(Makefile)
diff --git a/dependencies b/dependencies
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/linker_options b/linker_options
new file mode 100644
index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc
--- /dev/null
+++ b/linker_options
@@ -0,0 +1 @@
+
diff --git a/module.pmod.in b/module.pmod.in
new file mode 100644
index 0000000000000000000000000000000000000000..4f084dd799978c5aa0c1fe98b0413aa2b09f5c1f
--- /dev/null
+++ b/module.pmod.in
@@ -0,0 +1,91 @@
+/*
+  Author: Pontus Östlund <https://profiles.google.com/poppanator>
+
+  Permission to copy, modify, and distribute this source for any legal
+  purpose granted as long as my name is still attached to it. More
+  specifically, the GPL, LGPL and MPL licenses apply to this software.
+*/
+
+#pike __REAL_VERSION__
+#require constant(Tools._Sass)
+
+//! @ignore
+inherit Tools@module@;
+//! @endignore
+
+//! SCSS compiler
+class SCSS
+{
+  inherit Tools@module@._Api;
+
+  protected multiset(string) known_opts = (<
+    "output_style", "include_path", "source_map_file", "source_comments",
+    "source_map_embed" >);
+
+  //! Set options to the SASS compiler
+  //!
+  //! @param opts
+  //!  @mapping
+  //!   @member int "output_style"
+  //!    Any of the @[STYLE_NESTED], @[STYLE_EXPANDED], @[STYLE_COMPACT]
+  //!    or @[STYLE_COMPRESSED] constants. See also @[set_output_style()].
+  //!   @member string "include_path"
+  //!    Path to root of incude files. See also @[set_include_path()].
+  //!   @member string "source_map_file"
+  //!    File to write source map file to. Only has effect in @[compile_file()].
+  //!    See also @[set_source_map_file()].
+  //!   @member bool "source_comments"
+  //!    Turn on/off comments in the output containing info about the source
+  //!    file - line numbers and such. Default of @code{false@}. See also
+  //!    @[set_source_comments()].
+  //!   @member bool "source_map_embed"
+  //!    Turn on/off if a source map should be embedded in the output or not.
+  //!    Default is @code{false@}. See also @[set_source_map_embed()].
+  //!  @endmapping
+  void set_options(mapping(string:string|int) opts)
+  {
+    foreach (opts; string opt; string|int val) {
+      if (!known_opts[opt]) {
+        error("Unknown option %O!\n", opt);
+      }
+
+      switch (opt)
+      {
+        case "output_style":
+          if (!intp(val)) {
+            error("Value to set_output_style() must be an integer!\n");
+          }
+          set_output_style(val);
+          break;
+
+        case "include_path":
+          if (!stringp(val)) {
+            error("Value to set_include_path() must be a string!\n");
+          }
+          set_include_path(val);
+          break;
+
+        case "source_map_file":
+          if (!stringp(val)) {
+            error("Value to set_source_map_file() must be a string!\n");
+          }
+          set_source_map_file(val);
+          break;
+
+        case "source_map_embed":
+          if (!intp(val)) {
+            error("Value to set_source_map_embed() must be an int(0..1)\n");
+          }
+          set_source_map_embed(val);
+          break;
+
+        case "source_comments":
+          if (!intp(val)) {
+            error("Value to set_source_comments() must be an integer!\n");
+          }
+          set_source_comments(val);
+          break;
+      }
+    }
+  }
+}
diff --git a/sass.cmod b/sass.cmod
new file mode 100644
index 0000000000000000000000000000000000000000..e375efe3eab297c6db74259e519027a5400ab3b5
--- /dev/null
+++ b/sass.cmod
@@ -0,0 +1,425 @@
+/*
+|| This file is part of Pike. For copyright information see COPYRIGHT.
+|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
+|| for more information.
+*/
+
+#include <sass.h>
+
+#include "global.h"
+#include "interpret.h"
+#include "module.h"
+#include "stralloc.h"
+#include "svalue.h"
+#include "pike_types.h"
+
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_URL
+#undef PACKAGE_VERSION
+
+DECLARATIONS
+
+/*! @module Tools
+ */
+/*! @module Sass
+ */
+
+// #define SASS_DEBUG
+
+#ifdef SASS_DEBUG
+# define SASS_TRACE(X...) printf ("# " X)
+#else
+# define SASS_TRACE(X...) 0
+#endif
+
+typedef struct sass_opts {
+  int     style;
+  char*   include_path;
+  long    precision;
+  bool    comments;
+  char*   map_path;
+  bool    map_embed;
+} sass_opts;
+
+
+void set_options (sass_opts *opts, struct Sass_Context *ctx)
+{
+  struct Sass_Options *s_opts = sass_context_get_options (ctx);
+
+  sass_option_set_precision (s_opts, opts->precision);
+  sass_option_set_output_style (s_opts, opts->style);
+
+  if (opts->include_path) {
+    sass_option_set_include_path (s_opts, opts->include_path);
+  }
+
+  sass_option_set_source_comments (s_opts, opts->comments);
+
+  // if (opts->comments) {
+  // }
+
+  if (opts->map_path != NULL) {
+    sass_option_set_source_map_file (s_opts, opts->map_path);
+  }
+  else {
+    sass_option_set_source_map_embed (s_opts, opts->map_embed);
+  }
+}
+
+PIKECLASS _Api
+{
+  // CVAR sass_object *sobj;
+  CVAR sass_opts* options;
+
+  /*! @decl void set_include_path(string path)
+   *!
+   *! Set include path of @code{@imports@}
+   *!
+   *! @seealso
+   *!  get_include_path()
+   *!
+   *! @param path
+   */
+  PIKEFUN void set_include_path (string path)
+  {
+    if (path && path->len) {
+      if (access (path->str, F_OK) == -1) {
+        Pike_error ("Include path \"%s\" does not exist!\n", path->str);
+      }
+
+      THIS->options->include_path = strdup (path->str);
+    }
+  }
+
+  /*! @decl string get_include_path()
+   *!
+   *! Get include path of @code{@imports@}
+   *!
+   *! @seealso
+   *!  set_include_path()
+   */
+  PIKEFUN string get_include_path ()
+  {
+    const char* p = THIS->options->include_path;
+
+    if (p) {
+      push_text (p);
+    }
+    else {
+      push_int (0);
+    }
+  }
+
+  /*! @decl void get_output_style(int style)
+   *!
+   *! Set the output style. Default is @[Tools.Sass.STYLE_NESTED]
+   *!
+   *! @seealso
+   *!  @[get_output_style()]
+   *!
+   *! @param style
+   *!  See @[Tools.Sass.STYLE_NESTED], @[Tools.Sass.STYLE_EXPANDED],
+   *!  @[Tools.Sass.STYLE_COMPACT] and @[Tools.Sass.STYLE_COMPRESSED]
+   */
+  PIKEFUN void set_output_style (int style)
+  {
+    THIS->options->style = style;
+  }
+
+  /*! @decl int get_output_style(int style)
+   *!
+   *! Returns the output style.
+   *!
+   *! @seealso
+   *!  @[set_output_style()]
+   */
+  PIKEFUN int get_output_style ()
+  {
+    RETURN (THIS->options->style);
+  }
+
+  /*! @decl void set_source_comments(bool set)
+   *!
+   *! Set whether comments of source line number should be printed in the
+   *! generated CSS or not. Default is @code{false@}.
+   *!
+   *! @seealso
+   *!  @[get_source_comments()]
+   */
+  PIKEFUN void set_source_comments (int(0..1) set)
+  {
+    THIS->options->comments = set;
+  }
+
+  /*! @decl bool get_source_comments()
+   *!
+   *! Getter for @[set_source_comments()].
+   *!
+   *! @seealso
+   *!  @[set_source_comments()]
+   */
+  PIKEFUN int(0..1) get_source_comments ()
+  {
+    RETURN (THIS->options->comments);
+  }
+
+  /*! @decl void set_source_map_file(string path)
+   *!
+   *! Set the path of where to write the source map file. If this isn't set
+   *! no source map will be generated.
+   *!
+   *! @note
+   *!  This only has effect in @[compile_file()].
+   *!
+   *! @seealso
+   *!  @[get_source_map_file()], @[get_source_map_embed()],
+   *!  @[set_source_map_embed()]
+   */
+  PIKEFUN void set_source_map_file (string path)
+  {
+    THIS->options->map_path = strdup (path->str);
+  }
+
+
+  /*! @decl string get_source_map_file()
+   *!
+   *! Returns the path of the source map file.
+   *!
+   *! @seealso
+   *!  @[set_source_map_file()], @[set_source_map_embed()],
+   *!  @[get_source_map_embed()]
+   */
+  PIKEFUN string get_source_map_file ()
+  {
+    const char* f = THIS->options->map_path;
+
+    if (f) {
+      push_text (f);
+    }
+    else {
+      push_int (0);
+    }
+  }
+
+
+  /*! @decl void set_source_map_embed(bool embed)
+   *!
+   *! Should a source map be embedded in the compiled output?
+   *!
+   *! @seealso
+   *!  @[get_source_map_embed()], @[set_source_map_file()],
+   *!  @[get_source_map_file()]
+   *!
+   *! @param embed
+   */
+  PIKEFUN void set_source_map_embed (int(0..1) embed)
+  {
+    THIS->options->map_embed = embed;
+  }
+
+  /*! @decl bool get_source_map_embed()
+   *!
+   *! Will a source map be embedded or not?
+   *!
+   *! @seealso
+   *!  @[set_source_map_embed()], @[set_source_map_file()],
+   *!  @[get_source_map_file()]
+   */
+  PIKEFUN int(0..1) get_source_map_embed ()
+  {
+    RETURN (THIS->options->map_embed);
+  }
+
+
+  /*! @decl void set_precision(int(0..) p)
+   *!
+   *! Set the precision of floating point values
+   *!
+   *! @seealso
+   *!  @[get_precision()]
+   *!
+   *! @param p
+   */
+  PIKEFUN void set_precision (int(0..) p)
+  {
+    THIS->options->precision = p;
+  }
+
+
+  /*! @decl int(0..) get_precision()
+   *!
+   *! Returns the precision of floating point values
+   *!
+   *! @seealso
+   *!  @[set_precision()]
+   */
+  PIKEFUN int(0..) get_precision ()
+  {
+    RETURN (THIS->options->precision);
+  }
+
+
+  /*! @decl void compile_file (string in, string out)
+   *!
+   *! Compile the file @[in] and write it to @[out]
+   *!
+   *! @throws
+   *!  And error is thown if something fails.
+   *!
+   *! @param in
+   *!  The file to compile
+   *! @param out
+   *!  The file to write the output to
+   */
+  PIKEFUN void compile_file (string in, string out)
+  {
+    SASS_TRACE ("compile_file(%s)\n", in->str);
+
+    if (access (in->str, F_OK) == -1) {
+      Pike_error ("Input file \"%s\" does not exist!\n", in->str);
+    }
+
+    struct Sass_File_Context* ctx = sass_make_file_context (strdup (in->str));
+    struct Sass_Context* ctx_out = sass_file_context_get_context (ctx);
+
+    set_options (THIS->options, ctx_out);
+
+    int err = sass_compile_file_context (ctx);
+
+    if (err) {
+      const char* emsg = sass_context_get_error_message (ctx_out);
+      Pike_error ("Sass compile error (code: %d): %s\n",
+                  err, emsg);
+    }
+
+    const char* scss = sass_context_get_output_string (ctx_out);
+
+    FILE* fp;
+    fp = fopen (out->str, "wb");
+
+    if (!fp) {
+      Pike_error ("Error opening output file");
+    }
+
+    if (fprintf (fp, "%s", scss) < 0) {
+      fclose (fp);
+      Pike_error ("Error writing to output file");
+    }
+
+    fclose (fp);
+
+    struct Sass_Options *s_opts = sass_context_get_options (ctx_out);
+
+    if (sass_option_get_source_map_file (s_opts)) {
+      const char* smap = sass_context_get_source_map_string (ctx_out);
+
+      if ((err = sass_context_get_error_status (ctx_out))) {
+        Pike_error ("Failed generating source map (code: %ld): %s",
+                    err, sass_context_get_error_message (ctx_out));
+      }
+
+      fp = fopen (sass_option_get_source_map_file (s_opts), "wb");
+
+      if (!fp) {
+        Pike_error ("Error opening source map file");
+      }
+
+      if (fprintf (fp, "%s", smap) < 0) {
+        fclose (fp);
+        Pike_error ("Error writing to source map file");
+      }
+
+      fclose (fp);
+    }
+
+    sass_delete_file_context (ctx);
+  }
+
+
+  /*! @decl string compile_string(string source)
+   *!
+   *! Compile the string @[source]
+   *!
+   *! @param source
+   *!  The string to compile
+   */
+  PIKEFUN string compile_string (string source)
+  {
+    struct Sass_Data_Context* ctx;
+    ctx = sass_make_data_context (strdup (source->str));
+    struct Sass_Context* ctx_out = sass_data_context_get_context (ctx);
+
+    set_options (THIS->options, ctx_out);
+
+    sass_compile_data_context (ctx);
+
+    int err = sass_context_get_error_status (ctx_out);
+
+    if (err) {
+      Pike_error ("Sass error (code: %ld): %s",
+                  err, sass_context_get_error_message (ctx_out));
+    }
+
+    const char* out = sass_context_get_output_string (ctx_out);
+    push_text (out);
+
+    sass_delete_data_context (ctx);
+  }
+
+  INIT {
+    SASS_TRACE ("INIT Sass._Api\n");
+
+    THIS->options = (sass_opts *) malloc (sizeof (sass_opts));
+    memset (THIS->options, 0, sizeof (sass_opts));
+
+    THIS->options->style = SASS_STYLE_NESTED;
+    THIS->options->include_path = NULL;
+    THIS->options->precision = 5;
+    THIS->options->map_path = NULL;
+    // THIS->options->map_root = NULL;
+    THIS->options->comments = false;
+    THIS->options->map_embed = false;
+    // THIS->options->map_contents = false;
+    // THIS->options->omit_map_url = true;
+  }
+
+  EXIT {
+    SASS_TRACE ("EXIT Sass._Api\n");
+
+    if (THIS->options->include_path != NULL) {
+      free (THIS->options->include_path);
+    }
+
+    if (THIS->options->map_path != NULL) {
+      free (THIS->options->map_path);
+    }
+
+    free (THIS->options);
+  }
+}
+
+PIKE_MODULE_INIT
+{
+  add_string_constant ("LIBSASS_VERSION",   LIBSASS_VERSION, 0);
+
+  add_integer_constant ("STYLE_NESTED",     SASS_STYLE_NESTED,     0);
+  add_integer_constant ("STYLE_EXPANDED",   SASS_STYLE_EXPANDED,   0);
+  add_integer_constant ("STYLE_COMPACT",    SASS_STYLE_COMPACT,    0);
+  add_integer_constant ("STYLE_COMPRESSED", SASS_STYLE_COMPRESSED, 0);
+
+  INIT
+}
+
+
+PIKE_MODULE_EXIT
+{
+  EXIT
+}
+
+/*! @endmodule
+ */
+/*! @endmodule
+ */
diff --git a/testsuite.in b/testsuite.in
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391