diff --git a/quasi/Cargo.toml b/quasi/Cargo.toml
index 810d18ae..c6d207ee 100644
--- a/quasi/Cargo.toml
+++ b/quasi/Cargo.toml
@@ -6,6 +6,8 @@ license = "MIT/Apache-2.0"
 description = "A quasi-quoting macro system"
 repository = "https://github.com/erickt/rust-quasi"
 
-[dev-dependencies]
-aster = "*"
-quasi_macros = { version = "*", path = "../quasi_macros" }
+[features]
+with-syntex = ["syntex_syntax"]
+
+[dependencies]
+syntex_syntax = { version = "*", optional = true }
diff --git a/quasi/src/lib.rs b/quasi/src/lib.rs
index e7c73b96..608a7105 100644
--- a/quasi/src/lib.rs
+++ b/quasi/src/lib.rs
@@ -8,8 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(collections, rustc_private)]
+#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private))]
 
+#[cfg(feature = "with-syntex")]
+extern crate syntex_syntax as syntax;
+
+#[cfg(not(feature = "with-syntex"))]
 extern crate syntax;
 
 use std::rc::Rc;
diff --git a/quasi_codegen/Cargo.toml b/quasi_codegen/Cargo.toml
index 75aa2631..e1c5066a 100644
--- a/quasi_codegen/Cargo.toml
+++ b/quasi_codegen/Cargo.toml
@@ -6,5 +6,10 @@ license = "MIT/Apache-2.0"
 description = "A quasi-quoting macro system"
 repository = "https://github.com/erickt/rust-quasi"
 
+[features]
+with-syntex = ["syntex", "syntex_syntax", "aster/with-syntex"]
+
 [dependencies]
-aster = "*"
+aster = { version = "*", default-features = false }
+syntex = { version = "*", optional = true }
+syntex_syntax = { version = "*", optional = true }
diff --git a/quasi_codegen/src/lib.rs b/quasi_codegen/src/lib.rs
index 6d527849..6aa3af9a 100644
--- a/quasi_codegen/src/lib.rs
+++ b/quasi_codegen/src/lib.rs
@@ -8,12 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(plugin_registrar, unboxed_closures, rustc_private)]
+#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private))]
 
 extern crate aster;
-extern crate rustc;
+
+#[cfg(feature = "with-syntex")]
+extern crate syntex;
+
+#[cfg(feature = "with-syntex")]
+extern crate syntex_syntax as syntax;
+
+#[cfg(not(feature = "with-syntex"))]
 extern crate syntax;
 
+#[cfg(not(feature = "with-syntex"))]
+extern crate rustc;
+
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::ext::base::ExtCtxt;
@@ -35,7 +45,7 @@ fn expand_quote_tokens<'cx>(
     tts: &[ast::TokenTree],
 ) -> Box<base::MacResult + 'cx> {
     let (cx_expr, expr) = expand_tts(cx, sp, tts);
-    let expanded = expand_wrapper(sp, cx_expr, expr, &[&["quasi"]]);
+    let expanded = expand_wrapper(sp, cx_expr, expr);
     base::MacEager::expr(expanded)
 }
 
@@ -44,7 +54,12 @@ fn expand_quote_ty<'cx>(
     sp: Span,
     tts: &[ast::TokenTree]
 ) -> Box<base::MacResult + 'cx> {
-    let expanded = expand_parse_call(cx, sp, "parse_ty", vec!(), tts);
+    let expanded = expand_parse_call(
+        cx,
+        sp,
+        &["syntax", "parse", "parser", "Parser", "parse_ty"],
+        vec!(),
+        tts);
     base::MacEager::expr(expanded)
 }
 
@@ -53,7 +68,12 @@ fn expand_quote_expr<'cx>(
     sp: Span,
     tts: &[ast::TokenTree]
 ) -> Box<base::MacResult + 'cx> {
-    let expanded = expand_parse_call(cx, sp, "parse_expr", Vec::new(), tts);
+    let expanded = expand_parse_call(
+        cx,
+        sp,
+        &["syntax", "parse", "parser", "Parser", "parse_expr"],
+        Vec::new(),
+        tts);
     base::MacEager::expr(expanded)
 }
 
@@ -62,7 +82,12 @@ fn expand_quote_stmt<'cx>(
     sp: Span,
     tts: &[ast::TokenTree]
 ) -> Box<base::MacResult + 'cx> {
-    let expanded = expand_parse_call(cx, sp, "parse_stmt", vec!(), tts);
+    let expanded = expand_parse_call(
+        cx,
+        sp,
+        &["syntax", "parse", "parser", "Parser", "parse_stmt"],
+        vec!(),
+        tts);
     base::MacEager::expr(expanded)
 }
 
@@ -73,8 +98,12 @@ fn expand_quote_attr<'cx>(
 ) -> Box<base::MacResult + 'cx> {
     let builder = aster::AstBuilder::new().span(sp);
 
-    let expanded = expand_parse_call(cx, sp, "parse_attribute",
-                                    vec![builder.expr().bool(true)], tts);
+    let expanded = expand_parse_call(
+        cx,
+        sp,
+        &["syntax", "parse", "attr", "ParserAttr", "parse_attribute"],
+        vec![builder.expr().bool(true)],
+        tts);
 
     base::MacEager::expr(expanded)
 }
@@ -94,7 +123,7 @@ fn expand_quote_matcher<'cx>(
         .with_stmts(vector)
         .expr().id("tt");
     
-    let expanded = expand_wrapper(sp, cx_expr, block, &[&["quasi"]]);
+    let expanded = expand_wrapper(sp, cx_expr, block);
     base::MacEager::expr(expanded)
 }
 
@@ -103,7 +132,12 @@ fn expand_quote_pat<'cx>(
     sp: Span,
     tts: &[ast::TokenTree]
 ) -> Box<base::MacResult + 'cx> {
-    let expanded = expand_parse_call(cx, sp, "parse_pat", vec!(), tts);
+    let expanded = expand_parse_call(
+        cx,
+        sp,
+        &["syntax", "parse", "parser", "Parser", "parse_pat"],
+        vec!(),
+        tts);
     base::MacEager::expr(expanded)
 }
 
@@ -112,7 +146,12 @@ fn expand_quote_arm<'cx>(
     sp: Span,
     tts: &[ast::TokenTree]
 ) -> Box<base::MacResult + 'cx> {
-    let expanded = expand_parse_call(cx, sp, "parse_arm", vec!(), tts);
+    let expanded = expand_parse_call(
+        cx,
+        sp,
+        &["syntax", "parse", "parser", "Parser", "parse_arm"],
+        vec!(),
+        tts);
     base::MacEager::expr(expanded)
 }
 
@@ -121,7 +160,12 @@ fn expand_quote_block<'cx>(
     sp: Span,
     tts: &[ast::TokenTree]
 ) -> Box<base::MacResult + 'cx> {
-    let expanded = expand_parse_call(cx, sp, "parse_block", Vec::new(), tts);
+    let expanded = expand_parse_call(
+        cx,
+        sp,
+        &["syntax", "parse", "parser", "Parser", "parse_block"],
+        Vec::new(),
+        tts);
     base::MacEager::expr(expanded)
 }
 
@@ -130,8 +174,12 @@ fn expand_quote_item<'cx>(
     sp: Span,
     tts: &[ast::TokenTree]
 ) -> Box<base::MacResult + 'cx> {
-    let expanded = expand_parse_call(cx, sp, "parse_item",
-                                    vec!(), tts);
+    let expanded = expand_parse_call(
+        cx,
+        sp,
+        &["syntax", "parse", "parser", "Parser", "parse_item"],
+        vec!(),
+        tts);
     base::MacEager::expr(expanded)
 }
 
@@ -140,8 +188,12 @@ fn expand_quote_impl_item<'cx>(
     sp: Span,
     tts: &[ast::TokenTree]
 ) -> Box<base::MacResult + 'cx> {
-    let expanded = expand_parse_call(cx, sp, "parse_impl_item",
-                                    vec!(), tts);
+    let expanded = expand_parse_call(
+        cx,
+        sp,
+        &["syntax", "parse", "parser", "Parser", "parse_impl_item"],
+        vec!(),
+        tts);
     base::MacEager::expr(expanded)
 }
 
@@ -405,8 +457,14 @@ fn statements_mk_tt(tt: &ast::TokenTree, matcher: bool) -> Vec<P<ast::Stmt>> {
 
             let builder = builder.clone().span(sp);
 
-            let e_to_toks = builder.expr().method_call("to_tokens")
-                .id(ident)
+            let to_tokens = builder.path()
+                .global()
+                .ids(&["quasi", "ToTokens", "to_tokens"])
+                .build();
+
+            let e_to_toks = builder.expr().call()
+                .build_path(to_tokens)
+                .arg().addr_of().id(ident)
                 .arg().id("ext_cx")
                 .build();
 
@@ -596,8 +654,7 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
 
 fn expand_wrapper(sp: Span,
                   cx_expr: P<ast::Expr>,
-                  expr: P<ast::Expr>,
-                  imports: &[&[&str]]) -> P<ast::Expr> {
+                  expr: P<ast::Expr>) -> P<ast::Expr> {
     let builder = aster::AstBuilder::new().span(sp);
 
     // Explicitly borrow to avoid moving from the invoker (#16992)
@@ -607,23 +664,14 @@ fn expand_wrapper(sp: Span,
     let stmt_let_ext_cx = builder.stmt().let_id("ext_cx")
         .build(cx_expr_borrow);
 
-    let use_stmts = imports.iter()
-        .map(|path| {
-            builder.stmt().item()
-                .attr().allow(&["unused_imports"])
-                .use_().ids(path.iter()).build()
-                .glob()
-        });
-
     builder.expr().block()
-        .with_stmts(use_stmts)
         .with_stmt(stmt_let_ext_cx)
         .build_expr(expr)
 }
 
 fn expand_parse_call(cx: &ExtCtxt,
                      sp: Span,
-                     parse_method: &str,
+                     parse_method: &[&str],
                      arg_exprs: Vec<P<ast::Expr>> ,
                      tts: &[ast::TokenTree]) -> P<ast::Expr> {
     let builder = aster::AstBuilder::new().span(sp);
@@ -638,26 +686,49 @@ fn expand_parse_call(cx: &ExtCtxt,
         .id("ext_cx")
         .build();
 
+    let new_parser_from_tts_path = builder.path()
+        .global()
+        .ids(&["syntax", "parse", "new_parser_from_tts"])
+        .build();
+
     let new_parser_call = builder.expr().call()
-        .id("new_parser_from_tts")
+        .build_path(new_parser_from_tts_path)
         .with_arg(parse_sess_call)
         .with_arg(cfg_call)
         .with_arg(tts_expr)
         .build();
 
-    let expr = builder.expr().method_call(parse_method)
-        .build(new_parser_call)
+    let parse_method_path = builder.path()
+        .global()
+        .ids(parse_method)
+        .build();
+
+    let expr = builder.expr().call()
+        .build_path(parse_method_path)
+        .arg().mut_addr_of().build(new_parser_call)
         .with_args(arg_exprs)
         .build();
 
-    if parse_method == "parse_attribute" {
-        expand_wrapper(sp, cx_expr, expr, &[&["quasi"],
-                                            &["syntax", "parse", "attr"]])
-    } else {
-        expand_wrapper(sp, cx_expr, expr, &[&["quasi"]])
-    }
+    expand_wrapper(sp, cx_expr, expr)
+}
+
+#[cfg(feature = "with-syntex")]
+pub fn register(reg: &mut syntex::Registry) {
+    reg.add_macro("quote_tokens", expand_quote_tokens);
+    reg.add_macro("quote_ty", expand_quote_ty);
+    reg.add_macro("quote_expr", expand_quote_expr);
+    reg.add_macro("quote_matcher", expand_quote_matcher);
+    reg.add_macro("quote_stmt", expand_quote_stmt);
+    reg.add_macro("quote_attr", expand_quote_attr);
+    reg.add_macro("quote_pat", expand_quote_pat);
+    reg.add_macro("quote_arm", expand_quote_arm);
+    reg.add_macro("quote_block", expand_quote_block);
+    reg.add_macro("quote_item", expand_quote_item);
+    reg.add_macro("quote_impl_item", expand_quote_impl_item);
+    //reg.add_macro("quote_where_clause", expand_quote_where_clause);
 }
 
+#[cfg(not(feature = "syntex"))]
 pub fn register(reg: &mut rustc::plugin::Registry) {
     reg.register_macro("quote_tokens", expand_quote_tokens);
     reg.register_macro("quote_ty", expand_quote_ty);
diff --git a/quasi_macros/Cargo.toml b/quasi_macros/Cargo.toml
index c0eb71ad..070e01f2 100644
--- a/quasi_macros/Cargo.toml
+++ b/quasi_macros/Cargo.toml
@@ -12,3 +12,7 @@ plugin = true
 
 [dependencies]
 quasi_codegen = { version = "*", path = "../quasi_codegen" }
+
+[dev-dependencies]
+aster = "*"
+quasi = { version = "*", path = "../quasi" }
diff --git a/quasi_macros/tests/test.rs b/quasi_macros/tests/test.rs
new file mode 100644
index 00000000..88c2b8a8
--- /dev/null
+++ b/quasi_macros/tests/test.rs
@@ -0,0 +1,18 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(plugin, rustc_private)]
+#![plugin(quasi_macros)]
+
+extern crate aster;
+extern crate quasi;
+extern crate syntax;
+
+include!("../../quasi_tests/tests/test.rs.in");
diff --git a/quasi_tests/Cargo.toml b/quasi_tests/Cargo.toml
new file mode 100644
index 00000000..2835f938
--- /dev/null
+++ b/quasi_tests/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "quasi_tests"
+version = "0.3.0"
+authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
+license = "MIT/Apache-2.0"
+description = "A quasi-quoting macro system"
+repository = "https://github.com/erickt/rust-quasi"
+build = "build.rs"
+
+[build-dependencies]
+quasi_codegen = { version = "*", path = "../quasi_codegen", features = ["with-syntex"] }
+syntex = { version = "*" }
+
+[dev-dependencies]
+aster = { version = "*", features = ["with-syntex"] }
+quasi = { version = "*", path = "../quasi", features = ["with-syntex"] }
+syntex = { version = "*" }
+syntex_syntax = { version = "*" }
diff --git a/quasi_tests/build.rs b/quasi_tests/build.rs
new file mode 100644
index 00000000..702fad5d
--- /dev/null
+++ b/quasi_tests/build.rs
@@ -0,0 +1,16 @@
+extern crate syntex;
+extern crate quasi_codegen;
+
+use std::env;
+use std::path::Path;
+
+pub fn main() {
+    let out_dir = env::var_os("OUT_DIR").unwrap();
+    let mut registry = syntex::Registry::new();
+    quasi_codegen::register(&mut registry);
+
+    let src = Path::new("tests/test.rs.in");
+    let dst = Path::new(&out_dir).join("test.rs");
+
+    registry.expand("", &src, &dst).unwrap();
+}
diff --git a/quasi_tests/tests/test.rs b/quasi_tests/tests/test.rs
new file mode 100644
index 00000000..2fc47342
--- /dev/null
+++ b/quasi_tests/tests/test.rs
@@ -0,0 +1,15 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate aster;
+extern crate quasi;
+extern crate syntex_syntax as syntax;
+
+include!(concat!(env!("OUT_DIR"), "/test.rs"));
diff --git a/quasi/tests/test.rs b/quasi_tests/tests/test.rs.in
similarity index 92%
rename from quasi/tests/test.rs
rename to quasi_tests/tests/test.rs.in
index 38bc0563..64379004 100644
--- a/quasi/tests/test.rs
+++ b/quasi_tests/tests/test.rs.in
@@ -8,14 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(plugin, rustc_private)]
-#![plugin(quasi_macros)]
-
-extern crate aster;
-extern crate syntax;
-extern crate quasi;
-
 use syntax::ast;
+use syntax::codemap;
 use syntax::ext::base::ExtCtxt;
 use syntax::ext::expand;
 use syntax::parse;
@@ -23,17 +17,17 @@ use syntax::print::pprust;
 use syntax::owned_slice::OwnedSlice;
 
 fn make_ext_ctxt(sess: &parse::ParseSess) -> ExtCtxt {
-    let info = syntax::codemap::ExpnInfo {
-        call_site: syntax::codemap::DUMMY_SP,
-        callee: syntax::codemap::NameAndSpan {
+    let info = codemap::ExpnInfo {
+        call_site: codemap::DUMMY_SP,
+        callee: codemap::NameAndSpan {
             name: "test".to_string(),
-            format: syntax::codemap::MacroAttribute,
+            format: codemap::MacroAttribute,
             allow_internal_unstable: false,
             span: None
         }
     };
 
-    let cfg = vec![];
+    let cfg = Vec::new();
     let ecfg = expand::ExpansionConfig::default(String::new());
 
     let mut cx = ExtCtxt::new(&sess, cfg, ecfg);
@@ -213,7 +207,7 @@ fn test_quote_with_generics_and_where_clause() {
                 ast::WhereBoundPredicate {
                     span: syntax::codemap::DUMMY_SP,
                     bound_lifetimes: vec![],
-                    bounded_ty: quote_ty!(&cx, T),
+                    bounded_ty: builder.ty().id("T"),
                     bounds: OwnedSlice::from_vec(vec![
                         ast::TraitTyParamBound(
                             ast::PolyTraitRef {
@@ -247,10 +241,9 @@ fn test_stmt_semicolons() {
     let sess = parse::new_parse_sess();
     let cx = make_ext_ctxt(&sess);
 
-    let stmts = vec![
-        quote_stmt!(&cx, "let x = 1;"),
-        quote_stmt!(&cx, "let x = 2;"),
-    ];
+    let mut stmts = Vec::new();
+    stmts.push(quote_stmt!(&cx, "let x = 1;"));
+    stmts.push(quote_stmt!(&cx, "let y = 2;"));
 
     quote_block!(&cx, {
         $stmts