diff --git a/extra/ctags/authors.txt b/extra/ctags/authors.txt
new file mode 100644
index 0000000000..158cf94ea0
--- /dev/null
+++ b/extra/ctags/authors.txt
@@ -0,0 +1 @@
+Alfredo Beaumont
diff --git a/extra/ctags/ctags-docs.factor b/extra/ctags/ctags-docs.factor
new file mode 100644
index 0000000000..f2dbd8bc2b
--- /dev/null
+++ b/extra/ctags/ctags-docs.factor
@@ -0,0 +1,47 @@
+USING: help.syntax help.markup kernel prettyprint sequences strings ;
+IN: ctags
+
+ARTICLE: "ctags" "Ctags file"
+{ $emphasis "ctags" } " generates a index file of every factor word in ctags format as supported by vi and other editors. More information can be found at " { $url "http://en.wikipedia.org/wiki/Ctags" } "."
+{ $subsection ctags }
+{ $subsection ctags-write }
+{ $subsection ctag } ;
+
+HELP: ctags ( path -- )
+{ $values { "path" "a pathname string" } }
+{ $description "Generates a index file in ctags format and stores in " { $snippet "path" } "." }
+{ $examples
+  { $example
+    "USING: ctags ;"
+    "\"tags\" ctags-write"
+    ""
+  }
+} ;
+
+HELP: ctags-write ( seq path -- )
+{ $values { "seq" sequence }
+          { "path" "a pathname string" } }
+{ $description "Stores a " { $snippet "seq" } " in " { $snippet "path" } ". " { $snippet "seq" } " must be an association list with ctags format: key must be a valid word and value a sequence whose first element is a resource name and second element is a line number" }
+{ $examples
+  { $example
+    "USING: kernel ctags ;"
+    "{ { if  { \"resource:extra/unix/unix.factor\" 91 } } } \"tags\" ctags-write"
+    ""
+  }
+}
+{ $notes
+  { $snippet "tags" } " file will contain a single line: if\\t/path/to/factor/extra/unix/unix.factor\\t91" } ;
+
+HELP: ctag ( seq -- str )
+{ $values { "seq" sequence }
+          { "str" string } }
+{ $description "Outputs a string " { $snippet "str" } " in ctag format for sequence with two elements, first one must be a valid word and second one a sequence whose first element is a resource name and second element is a line number" }
+{ $examples
+  { $example
+    "USING: kernel ctags ;"
+    "{ if  { \"resource:extra/unix/unix.factor\" 91 } } ctag ."
+    "\"if\\t/path/to/factor/extra/unix/unix.factor\\t91\""
+  }
+} ;
+
+ABOUT: "ctags"
\ No newline at end of file
diff --git a/extra/ctags/ctags-tests.factor b/extra/ctags/ctags-tests.factor
new file mode 100644
index 0000000000..dc6e402653
--- /dev/null
+++ b/extra/ctags/ctags-tests.factor
@@ -0,0 +1,7 @@
+USING: kernel ctags tools.test io.backend sequences ;
+IN: columns.tests
+
+[ t ] [
+  "if\t" "resource:extra/unix/unix.factor" normalize-path "\t91" 3append
+  { if  { "resource:extra/unix/unix.factor" 91 } } ctag =
+] unit-test
\ No newline at end of file
diff --git a/extra/ctags/ctags.factor b/extra/ctags/ctags.factor
new file mode 100644
index 0000000000..5480772ba1
--- /dev/null
+++ b/extra/ctags/ctags.factor
@@ -0,0 +1,34 @@
+! Copyright (C) 2008 Alfredo Beaumont
+! See http://factorcode.org/license.txt for BSD license.
+
+! Simple Ctags generator
+! Alfredo Beaumont <alfredo.beaumont@gmail.com>
+
+USING: kernel sequences io io.files io.backend
+io.encodings.ascii math.parser vocabs definitions
+namespaces words sorting ;
+IN: ctags
+
+: ctag ( seq -- str )
+  [
+    dup first ?word-name %
+    "\t" %
+    second dup first normalize-path %
+    "\t" %
+    second number>string %
+  ] "" make ;
+
+: ctags-write ( seq path -- )
+  ascii [ [ ctag print ] each ] with-file-writer ;
+
+: (ctags) ( -- seq )
+  { } all-words [
+    dup where [
+      { } 2sequence suffix
+    ] [
+      drop
+    ] if*
+  ] each ;
+
+: ctags ( path -- )
+  (ctags) sort-keys swap ctags-write ;
\ No newline at end of file
diff --git a/extra/ctags/summary.txt b/extra/ctags/summary.txt
new file mode 100644
index 0000000000..2025e02521
--- /dev/null
+++ b/extra/ctags/summary.txt
@@ -0,0 +1 @@
+Ctags generator