Repository: cobalt-org/liquid-rust
Pull request #384 (2020-01-15 01:14:24)

Support 2018 Edition
With how liquid is structured and how 2018 changed `use`, we needed a drastic change to support 2018 edition,.


Patch:
diff --git a/Cargo.toml b/Cargo.toml
index cbdf2d6..5db1a9b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,6 +5,7 @@ members = [
   "crates/compiler",
   "crates/interpreter",
   "crates/derive",
+  "crates/core",
   "crates/help-md",
   "crates/bin",
   "crates/kstring",
@@ -21,6 +22,7 @@ readme = "README.md"
 categories = ["template-engine"]
 keywords = ["liquid", "template", "templating", "language", "html"]
 license = "MIT"
+edition = "2018"
 
 [badges]
 azure-devops = { project = "cobalt-org", pipeline = "liquid-rust" }
@@ -41,11 +43,7 @@ itertools = "0.8.0"
 url = "1.5"
 doc-comment = "0.3"
 kstring = { version = "0.1.0", path = "crates/kstring" }
-liquid-error = { version = "^0.19", path = "crates/error" }
-liquid-value = { version = "^0.19", path = "crates/value" }
-liquid-compiler = { version = "^0.19", path = "crates/compiler" }
-liquid-interpreter = { version = "^0.19", path = "crates/interpreter" }
-liquid-derive = { version = "^0.19", path = "crates/derive" }
+liquid-core = { version = "^0.19", path = "crates/core" }
 
 serde = { version = "1.0", optional = true, features = ["derive"] }
 deunicode = "1.0.0"
diff --git a/README.md b/README.md
index c299ec2..54fbc53 100644
--- a/README.md
+++ b/README.md
@@ -35,23 +35,16 @@ To include liquid in your project add the following to your Cargo.toml:
 liquid = "0.18"
 ```
 
-Now you can use the crate in your code:
-
-```rust
-extern crate liquid;
-```
-
 Example:
 
 ```rust
-extern crate liquid;
-
 let template = liquid::ParserBuilder::with_liquid()
     .build().unwrap()
     .parse("Liquid! {{num | minus: 2}}").unwrap();
 
-let mut globals = liquid::value::Object::new();
-globals.insert("num".into(), liquid::value::Value::scalar(4f64));
+let mut globals = liquid::object!({
+    "num": 4f64
+});
 
 let output = template.render(&globals).unwrap();
 assert_eq!(output, "Liquid! 2".to_string());
diff --git a/benches/handlebars_baseline.rs b/benches/handlebars_baseline.rs
index 86e1108..9789ddd 100644
--- a/benches/handlebars_baseline.rs
+++ b/benches/handlebars_baseline.rs
@@ -1,8 +1,7 @@
 #![feature(test)]
-extern crate handlebars;
+
 #[macro_use]
 extern crate serde_derive;
-extern crate serde_json;
 
 extern crate test;
 
diff --git a/benches/handlebars_liquid.rs b/benches/handlebars_liquid.rs
index 8090531..7999a95 100644
--- a/benches/handlebars_liquid.rs
+++ b/benches/handlebars_liquid.rs
@@ -1,9 +1,9 @@
 #![feature(test)]
 
-extern crate serde_yaml;
+use serde_yaml;
 extern crate test;
 
-extern crate liquid;
+use liquid;
 
 // Mirrors handlebars' benchmark
 static ITERATE: &'static str = "<html>
@@ -53,7 +53,7 @@ fn render_template(b: &mut test::Bencher) {
         .parse(ITERATE)
         .expect("Benchmark template parsing failed");
 
-    let data: liquid::value::Object =
+    let data: liquid::Object =
         serde_yaml::from_str(ITERATE_OBJECT).expect("Benchmark object parsing failed");
 
     template.render(&data).unwrap();
@@ -72,12 +72,8 @@ fn large_loop_helper(b: &mut test::Bencher) {
         .parse(LOOP)
         .expect("Benchmark template parsing failed");
 
-    let data_wrapper = liquid::value::Value::array(
-        (1..1000)
-            .map(|i| format!("n={}", i))
-            .map(liquid::value::Value::scalar),
-    );
-    let row_wrapper = liquid::value::object!({
+    let data_wrapper: Vec<_> = (1..1000).map(|i| format!("n={}", i)).collect();
+    let row_wrapper = liquid::object!({
         "real": data_wrapper.clone(),
         "dummy": data_wrapper.clone(),
     });
diff --git a/benches/liquid.rs b/benches/liquid.rs
index 1fb698f..ab5b608 100644
--- a/benches/liquid.rs
+++ b/benches/liquid.rs
@@ -1,9 +1,8 @@
 #![feature(test)]
 
-extern crate serde_yaml;
 extern crate test;
 
-extern crate liquid;
+use liquid;
 
 static TEXT_ONLY: &'static str = "Hello World";
 
@@ -26,7 +25,7 @@ fn bench_render_text(b: &mut test::Bencher) {
         .parse(TEXT_ONLY)
         .expect("Benchmark template parsing failed");
 
-    let data = liquid::value::Object::new();
+    let data = liquid::Object::new();
 
     template.render(&data).unwrap();
     b.iter(|| template.render(&data));
diff --git a/benches/tera_bigcontext_baseline.rs b/benches/tera_bigcontext_baseline.rs
index c10e7c8..4d9aca6 100644
--- a/benches/tera_bigcontext_baseline.rs
+++ b/benches/tera_bigcontext_baseline.rs
@@ -1,6 +1,5 @@
 #![feature(test)]
-extern crate serde_json;
-extern crate tera;
+
 extern crate test;
 #[macro_use]
 extern crate serde_derive;
diff --git a/benches/tera_bigcontext_liquid.rs b/benches/tera_bigcontext_liquid.rs
index 3c43942..fef541e 100644
--- a/benches/tera_bigcontext_liquid.rs
+++ b/benches/tera_bigcontext_liquid.rs
@@ -2,13 +2,13 @@
 
 extern crate test;
 
-extern crate liquid;
+use liquid;
 
 #[bench]
 fn bench_big_loop_big_object(b: &mut test::Bencher) {
     const NUM_OBJECTS: usize = 100;
-    let objects = (0..NUM_OBJECTS).map(|i| {
-        let data_wrapper= liquid::value::object!({
+    let objects: Vec<_> = (0..NUM_OBJECTS).map(|i| {
+        let data_wrapper= liquid::object!({
             "i": (i as i32),
             "v": "Meta
 Before we get to the details, two important notes about the ownership system.
@@ -16,19 +16,18 @@ Rust has a focus on safety and speed. It accomplishes these goals through many 
 However, this system does have a certain cost: learning curve. Many new users to Rust experience something we like to call ‘fighting with the borrow checker’, where the Rust compiler refuses to compile a program that the author thinks is valid. This often happens because the programmer’s mental model of how ownership should work doesn’t match the actual rules that Rust implements. You probably will experience similar things at first. There is good news, however: more experienced Rust developers report that once they work with the rules of the ownership system for a period of time, they fight the borrow checker less and less.
 With that in mind, let’s learn about borrowing.",
         });
-        liquid::value::value!({
-            "field_a": liquid::value::Value::Object(data_wrapper.clone()),
-            "field_b": liquid::value::Value::Object(data_wrapper.clone()),
-            "field_c": liquid::value::Value::Object(data_wrapper.clone()),
-            "field_d": liquid::value::Value::Object(data_wrapper.clone()),
-            "field_e": liquid::value::Value::Object(data_wrapper.clone()),
-            "field_f": liquid::value::Value::Object(data_wrapper.clone()),
+        liquid::object!({
+            "field_a": data_wrapper.clone(),
+            "field_b": data_wrapper.clone(),
+            "field_c": data_wrapper.clone(),
+            "field_d": data_wrapper.clone(),
+            "field_e": data_wrapper.clone(),
+            "field_f": data_wrapper.clone(),
         })
     }).collect();
-    let data: liquid::value::Object =
-        vec![("objects".into(), liquid::value::Value::Array(objects))]
-            .into_iter()
-            .collect();
+    let data = liquid::object!({
+        "objects": objects,
+    });
 
     let parser = liquid::ParserBuilder::with_liquid()
         .extra_filters()
diff --git a/benches/tera_template_baseline.rs b/benches/tera_template_baseline.rs
index 2ab6711..e760b29 100644
--- a/benches/tera_template_baseline.rs
+++ b/benches/tera_template_baseline.rs
@@ -1,5 +1,5 @@
 #![feature(test)]
-extern crate tera;
+
 extern crate test;
 #[macro_use]
 extern crate serde_derive;
diff --git a/benches/tera_template_liquid.rs b/benches/tera_template_liquid.rs
index 0c5ec88..4df7ce1 100644
--- a/benches/tera_template_liquid.rs
+++ b/benches/tera_template_liquid.rs
@@ -1,9 +1,9 @@
 #![feature(test)]
 
-extern crate serde_yaml;
+use serde_yaml;
 extern crate test;
 
-extern crate liquid;
+use liquid;
 
 // Benches from https://github.com/djc/template-benchmarks-rs
 
@@ -11,14 +11,12 @@ extern crate liquid;
 pub fn big_table(b: &mut test::Bencher) {
     // 100 instead of 50 in the original benchmark to make the time bigger
     let size = 100;
-    let mut table = Vec::with_capacity(size);
-    for _ in 0..size {
-        let mut inner = Vec::with_capacity(size);
-        for i in 0..size {
-            inner.push(liquid::value::Value::scalar(i as i32));
-        }
-        table.push(liquid::value::Value::array(inner));
-    }
+    let table: Vec<_> = (0..size)
+        .map(|_| {
+            let inner: Vec<_> = (0..size).map(|i| i as i32).collect();
+            inner
+        })
+        .collect();
 
     let parser = liquid::ParserBuilder::with_liquid()
         .extra_filters()
@@ -28,7 +26,7 @@ pub fn big_table(b: &mut test::Bencher) {
         .parse(BIG_TABLE_TEMPLATE)
         .expect("Benchmark template parsing failed");
 
-    let data = liquid::value::object!({ "table": table });
+    let data = liquid::object!({ "table": table });
 
     template.render(&data).unwrap();
     b.iter(|| template.render(&data));
@@ -50,7 +48,7 @@ pub fn teams(b: &mut test::Bencher) {
         .parse(TEAMS_TEMPLATE)
         .expect("Benchmark template parsing failed");
 
-    let data: liquid::value::Object =
+    let data: liquid::Object =
         serde_yaml::from_str(TEAMS_DATA).expect("Benchmark object parsing failed");
 
     template.render(&data).unwrap();
diff --git a/benches/tera_tera_baseline.rs b/benches/tera_tera_baseline.rs
index a793bd1..f9af5a6 100644
--- a/benches/tera_tera_baseline.rs
+++ b/benches/tera_tera_baseline.rs
@@ -1,9 +1,9 @@
 #![feature(test)]
-extern crate tera;
+
 extern crate test;
 #[macro_use]
 extern crate serde_derive;
-extern crate serde_json;
+use serde_json;
 
 use tera::{escape_html, Context, Template, Tera, Value};
 
diff --git a/benches/tera_tera_liquid.rs b/benches/tera_tera_liquid.rs
index a944038..b8444fa 100644
--- a/benches/tera_tera_liquid.rs
+++ b/benches/tera_tera_liquid.rs
@@ -1,10 +1,9 @@
 #![feature(test)]
 
-extern crate serde_json;
-extern crate serde_yaml;
+use serde_yaml;
 extern crate test;
 
-extern crate liquid;
+use liquid;
 
 static VARIABLE_ONLY: &'static str = "{{product.name}}";
 
@@ -51,7 +50,7 @@ fn bench_rendering_only_variable(b: &mut test::Bencher) {
         .parse(VARIABLE_ONLY)
         .expect("Benchmark template parsing failed");
 
-    let data: liquid::value::Object =
+    let data: liquid::Object =
         serde_yaml::from_str(PRODUCTS).expect("Benchmark object parsing failed");
 
     template.render(&data).unwrap();
@@ -68,46 +67,43 @@ fn bench_rendering_basic_template(b: &mut test::Bencher) {
         .parse(SIMPLE_TEMPLATE)
         .expect("Benchmark template parsing failed");
 
-    let data: liquid::value::Object =
+    let data: liquid::Object =
         serde_yaml::from_str(PRODUCTS).expect("Benchmark object parsing failed");
 
     template.render(&data).unwrap();
     b.iter(|| template.render(&data));
 }
 
-fn deep_object() -> liquid::value::Object {
-    let data = r#"{
-                    "foo": {
-                        "bar": {
-                            "goo": {
-                                "moo": {
-                                    "cows": [
-                                        {
-                                            "name": "betsy",
-                                            "age" : 2,
-                                            "temperament": "calm"
-                                        },
-                                        {
-                                            "name": "elsie",
-                                            "age": 3,
-                                            "temperament": "calm"
-                                        },
-                                        {
-                                            "name": "veal",
-                                            "age": 1,
-                                            "temperament": "ornery"
-                                        }
-                                    ]
+fn deep_object() -> liquid::Object {
+    liquid::object!({
+        "deep_object": {
+            "foo": {
+                "bar": {
+                    "goo": {
+                        "moo": {
+                            "cows": [
+                                {
+                                    "name": "betsy",
+                                    "age" : 2,
+                                    "temperament": "calm"
+                                },
+                                {
+                                    "name": "elsie",
+                                    "age": 3,
+                                    "temperament": "calm"
+                                },
+                                {
+                                    "name": "veal",
+                                    "age": 1,
+                                    "temperament": "ornery"
                                 }
-                            }
+                            ]
                         }
                     }
-                  }"#;
-
-    let data = serde_json::from_str(data).unwrap();
-    vec![("deep_object".into(), liquid::value::Value::Object(data))]
-        .into_iter()
-        .collect()
+                }
+            }
+        }
+    })
 }
 
 #[bench]
diff --git a/crates/bin/src/main.rs b/crates/bin/src/main.rs
index c580b5f..584a493 100644
--- a/crates/bin/src/main.rs
+++ b/crates/bin/src/main.rs
@@ -1,8 +1,6 @@
 // Allow zero pointers for lazy_static. Otherwise clippy will complain.
 #![allow(unknown_lints)]
 
-use liquid;
-
 use serde_json;
 use serde_yaml;
 
@@ -21,17 +19,17 @@ struct Error {
 
 impl std::error::Error for Error {}
 
-fn load_yaml(path: &path::Path) -> Result<liquid::value::Value, Box<dyn std::error::Error>> {
+fn load_yaml(path: &path::Path) -> Result<liquid::Object, Box<dyn std::error::Error>> {
     let f = fs::File::open(path)?;
     serde_yaml::from_reader(f).map_err(|e| e.into())
 }
 
-fn load_json(path: &path::Path) -> Result<liquid::value::Value, Box<dyn std::error::Error>> {
+fn load_json(path: &path::Path) -> Result<liquid::Object, Box<dyn std::error::Error>> {
     let f = fs::File::open(path)?;
     serde_json::from_reader(f).map_err(|e| e.into())
 }
 
-fn build_context(path: &path::Path) -> Result<liquid::value::Object, Box<dyn std::error::Error>> {
+fn build_context(path: &path::Path) -> Result<liquid::Object, Box<dyn std::error::Error>> {
     let extension = path.extension().unwrap_or_else(|| ffi::OsStr::new(""));
     let value = if extension == ffi::OsStr::new("yaml") {
         load_yaml(path)
@@ -40,10 +38,6 @@ fn build_context(path: &path::Path) -> Result<liquid::value::Object, Box<dyn std
     } else {
         Err(Error::new("Unsupported file type"))?
     }?;
-    let value = match value {
-        liquid::value::Value::Object(o) => Ok(o),
-        _ => Err(Error::new("File must be an object")),
-    }?;
 
     Ok(value)
 }
@@ -75,7 +69,7 @@ fn run() -> Result<i32, Box<dyn std::error::Error>> {
         .as_ref()
         .map(|p| build_context(p.as_path()))
         .map_or(Ok(None), |r| r.map(Some))?
-        .unwrap_or_else(liquid::value::Object::new);
+        .unwrap_or_else(liquid::Object::new);
     let output = template.render(&data)?;
     match args.output {
         Some(path) => {
diff --git a/crates/compiler/Cargo.toml b/crates/compiler/Cargo.toml
index 1953c82..2e0744f 100644
--- a/crates/compiler/Cargo.toml
+++ b/crates/compiler/Cargo.toml
@@ -3,7 +3,7 @@ name = "liquid-compiler"
 version = "0.19.0"
 authors = ["Johann Hofmann <mail@johann-hofmann.com>"]
 description = "The liquid templating language for Rust"
-repository = "https://github.com/cobalt-org/liquid-rust/tree/master/liquid-compiler"
+repository = "https://github.com/cobalt-org/liquid-rust/tree/master/crate/compiler"
 documentation = "https://docs.rs/liquid-compiler"
 readme = "README.md"
 categories = ["template-engine"]
diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml
new file mode 100644
index 0000000..16e8c25
--- /dev/null
+++ b/crates/core/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+name = "liquid-core"
+version = "0.19.0"
+authors = ["Ed Page <eopage@gmail.com>"]
+description = "Core liquid functionality"
+repository = "https://github.com/cobalt-org/liquid-rust/tree/master/crate/core"
+documentation = "https://docs.rs/liquid-core"
+readme = "README.md"
+categories = ["template-engine"]
+keywords = ["liquid", "template", "templating", "language", "html"]
+license = "MIT"
+edition = "2018"
+
+[dependencies]
+liquid-error = { version = "^0.19", path = "../error" }
+liquid-value = { version = "^0.19", path = "../value" }
+liquid-compiler = { version = "^0.19", path = "../compiler" }
+liquid-interpreter = { version = "^0.19", path = "../interpreter" }
+liquid-derive = { version = "^0.19", path = "../derive" }
diff --git a/crates/core/LICENSE b/crates/core/LICENSE
new file mode 100644
index 0000000..135cef1
--- /dev/null
+++ b/crates/core/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 cobalt-org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/crates/core/README.md b/crates/core/README.md
new file mode 100644
index 0000000..269c61f
--- /dev/null
+++ b/crates/core/README.md
@@ -0,0 +1,18 @@
+liquid-core
+===========
+
+> [Liquid templating](http://liquidmarkup.org/) for Rust
+
+[![Build Status](https://dev.azure.com/cobalt-org/cobalt-org/_apis/build/status/liquid-rust?branchName=master)](https://dev.azure.com/cobalt-org/cobalt-org/_build/latest?definitionId=1&branchName=master)
+[![Crates Status](https://img.shields.io/crates/v/liquid.svg)](https://crates.io/crates/liquid)
+[![Dependency Status](https://dependencyci.com/github/cobalt-org/liquid-rust/badge)](https://dependencyci.com/github/cobalt-org/liquid-rust)
+
+Usage
+----------
+
+To include liquid in your project add the following to your Cargo.toml:
+
+```toml
+[dependencies]
+liquid-core = "0.16"
+```
diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs
new file mode 100644
index 0000000..4e0cded
--- /dev/null
+++ b/crates/core/src/lib.rs
@@ -0,0 +1,31 @@
+pub mod compiler {
+    pub use liquid_compiler::*;
+}
+pub mod error {
+    pub use liquid_error::*;
+}
+pub mod interpreter {
+    pub use liquid_interpreter::*;
+}
+pub mod value {
+    pub use liquid_value::*;
+}
+
+pub use liquid_compiler::Language;
+pub use liquid_compiler::TagTokenIter;
+pub use liquid_compiler::{BlockReflection, ParseBlock, TagBlock};
+pub use liquid_compiler::{Filter, FilterParameters, FilterReflection, ParseFilter};
+pub use liquid_compiler::{ParseTag, TagReflection};
+pub use liquid_derive::{
+    Display_filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+pub use liquid_error::{Error, Result};
+pub use liquid_interpreter::Context;
+pub use liquid_interpreter::Expression;
+pub use liquid_interpreter::Renderable;
+pub use liquid_interpreter::Template;
+pub use liquid_value::object;
+pub use liquid_value::to_object;
+pub use liquid_value::Object;
+pub use liquid_value::Value;
+pub use liquid_value::{ObjectView, ValueView};
diff --git a/crates/derive/Cargo.toml b/crates/derive/Cargo.toml
index 9d7d20d..f19322b 100644
--- a/crates/derive/Cargo.toml
+++ b/crates/derive/Cargo.toml
@@ -7,6 +7,7 @@ readme = "README.md"
 categories = ["template-engine"]
 keywords = ["liquid", "template", "templating", "language", "html"]
 license = "MIT"
+edition = "2018"
 
 [lib]
 proc-macro = true
diff --git a/crates/derive/src/filter/display.rs b/crates/derive/src/filter/display.rs
index 4c55386..98221cd 100644
--- a/crates/derive/src/filter/display.rs
+++ b/crates/derive/src/filter/display.rs
@@ -1,4 +1,4 @@
-use helpers::*;
+use crate::helpers::*;
 use proc_macro2::*;
 use proc_quote::*;
 use syn::*;
@@ -148,7 +148,7 @@ impl<'a> FilterStruct<'a> {
 }
 
 /// Generates implementation of `Display`.
-fn generate_impl_display(filter: &FilterStruct) -> TokenStream {
+fn generate_impl_display(filter: &FilterStruct<'_>) -> TokenStream {
     let FilterStruct {
         filter_name,
         parameters,
diff --git a/crates/derive/src/filter/from_filter_parameters.rs b/crates/derive/src/filter/from_filter_parameters.rs
index ce3a95f..4bc0d7c 100644
--- a/crates/derive/src/filter/from_filter_parameters.rs
+++ b/crates/derive/src/filter/from_filter_parameters.rs
@@ -1,4 +1,4 @@
-use helpers::*;
+use crate::helpers::*;
 use proc_macro2::*;
 use proc_quote::*;
 use syn::*;
@@ -169,7 +169,7 @@ struct FilterField<'a> {
 }
 
 /// Generates implementation of `From<FilterParameters>`.
-fn generate_from_filter_parameters(filter: &FilterStruct) -> TokenStream {
+fn generate_from_filter_parameters(filter: &FilterStruct<'_>) -> TokenStream {
     let FilterStruct {
         parameters_struct_name,
         fields,
diff --git a/crates/derive/src/filter_parameters.rs b/crates/derive/src/filter_parameters.rs
index 3cf6b8c..b66a506 100644
--- a/crates/derive/src/filter_parameters.rs
+++ b/crates/derive/src/filter_parameters.rs
@@ -1,4 +1,4 @@
-use helpers::*;
+use crate::helpers::*;
 use proc_macro2::*;
 use proc_quote::*;
 use std::str::FromStr;
@@ -134,7 +134,7 @@ impl<'a> FilterParametersFields<'a> {
     ///
     /// All optional positional parameters must appear after every required positional parameter.
     /// If this function returns `Some`, the macro is supposed to fail to compile.
-    fn required_after_optional(&self) -> Option<&FilterParameter> {
+    fn required_after_optional(&self) -> Option<&FilterParameter<'_>> {
         self.parameters
             .iter()
             .filter(|parameter| parameter.is_positional())
@@ -195,7 +195,7 @@ impl<'a> FilterParameter<'a> {
     const ERROR_INVALID_TYPE: &'static str = "Invalid type. All fields in FilterParameters must be either of type `Expression` or `Option<Expression>`";
 
     /// Helper function for `validate_filter_parameter_fields()`.
-    /// Given `::liquid::interpreter::Expression`, returns `Expression`.
+    /// Given `::liquid_core::interpreter::Expression`, returns `Expression`.
     fn get_type_name(ty: &Type) -> Result<&PathSegment> {
         match ty {
             Type::Path(ty) => {
@@ -451,7 +451,10 @@ impl FilterParameterMeta {
 }
 
 /// Generates the statement that assigns the next positional argument.
-fn generate_construct_positional_field(field: &FilterParameter, required: usize) -> TokenStream {
+fn generate_construct_positional_field(
+    field: &FilterParameter<'_>,
+    required: usize,
+) -> TokenStream {
     let name = &field.name;
 
     if field.is_optional() {
@@ -462,7 +465,7 @@ fn generate_construct_positional_field(field: &FilterParameter, required: usize)
         let plural = if required == 1 { None } else { Some("s") };
         quote! {
             let #name = args.positional.next().ok_or_else(||
-                ::liquid::error::Error::with_msg("Invalid number of arguments")
+                ::liquid_core::error::Error::with_msg("Invalid number of arguments")
                     .context("cause", concat!("expected at least ", #required, " positional argument", #plural))
             )?;
         }
@@ -470,7 +473,7 @@ fn generate_construct_positional_field(field: &FilterParameter, required: usize)
 }
 
 /// Generates the statement that evaluates the `Expression`
-fn generate_evaluate_field(field: &FilterParameter) -> TokenStream {
+fn generate_evaluate_field(field: &FilterParameter<'_>) -> TokenStream {
     let name = &field.name;
     let liquid_name = field.liquid_name();
     let ty = &field.meta.ty;
@@ -481,7 +484,7 @@ fn generate_evaluate_field(field: &FilterParameter) -> TokenStream {
             .as_scalar()
             .and_then(|s| s.to_integer())
             .ok_or_else(||
-                ::liquid::error::Error::with_msg("Invalid argument")
+                ::liquid_core::error::Error::with_msg("Invalid argument")
                     .context("argument", #liquid_name)
                     .context("cause", "Whole number expected")
             )?
@@ -490,7 +493,7 @@ fn generate_evaluate_field(field: &FilterParameter) -> TokenStream {
             .as_scalar()
             .and_then(|s| s.to_float())
             .ok_or_else(||
-                ::liquid::error::Error::with_msg("Invalid argument")
+                ::liquid_core::error::Error::with_msg("Invalid argument")
                     .context("argument", #liquid_name)
                     .context("cause", "Fractional number expected")
             )?
@@ -499,7 +502,7 @@ fn generate_evaluate_field(field: &FilterParameter) -> TokenStream {
             .as_scalar()
             .and_then(|s| s.to_bool())
             .ok_or_else(||
-                ::liquid::error::Error::with_msg("Invalid argument")
+                ::liquid_core::error::Error::with_msg("Invalid argument")
                     .context("argument", #liquid_name)
                     .context("cause", "Boolean expected")
             )?
@@ -508,7 +511,7 @@ fn generate_evaluate_field(field: &FilterParameter) -> TokenStream {
             .as_scalar()
             .and_then(|s| s.to_date_time())
             .ok_or_else(||
-                ::liquid::error::Error::with_msg("Invalid argument")
+                ::liquid_core::error::Error::with_msg("Invalid argument")
                     .context("argument", #liquid_name)
                     .context("cause", "DateTime expected")
             )?
@@ -517,7 +520,7 @@ fn generate_evaluate_field(field: &FilterParameter) -> TokenStream {
             .as_scalar()
             .and_then(|s| s.to_date())
             .ok_or_else(||
-                ::liquid::error::Error::with_msg("Invalid argument")
+                ::liquid_core::error::Error::with_msg("Invalid argument")
                     .context("argument", #liquid_name)
                     .context("cause", "Date expected")
             )?
@@ -542,7 +545,7 @@ fn generate_evaluate_field(field: &FilterParameter) -> TokenStream {
 }
 
 /// Generates the match arm that assigns the given keyword argument.
-fn generate_keyword_match_arm(field: &FilterParameter) -> TokenStream {
+fn generate_keyword_match_arm(field: &FilterParameter<'_>) -> TokenStream {
     let rust_name = &field.name;
     let liquid_name = field.liquid_name();
 
@@ -550,13 +553,13 @@ fn generate_keyword_match_arm(field: &FilterParameter) -> TokenStream {
         #liquid_name => if #rust_name.is_none() {
             #rust_name = ::std::option::Option::Some(arg.1);
         } else {
-            return ::std::result::Result::Err(::liquid::error::Error::with_msg(concat!("Multiple definitions of `", #liquid_name, "`")));
+            return ::std::result::Result::Err(::liquid_core::error::Error::with_msg(concat!("Multiple definitions of `", #liquid_name, "`")));
         },
     }
 }
 
 /// Generates implementation of `FilterParameters`.
-fn generate_impl_filter_parameters(filter_parameters: &FilterParameters) -> TokenStream {
+fn generate_impl_filter_parameters(filter_parameters: &FilterParameters<'_>) -> TokenStream {
     let FilterParameters {
         name,
         evaluated_name,
@@ -583,7 +586,7 @@ fn generate_impl_filter_parameters(filter_parameters: &FilterParameters) -> Toke
             Some("s")
         };
         quote! {
-            ::liquid::error::Error::with_msg("Invalid number of positional arguments")
+            ::liquid_core::error::Error::with_msg("Invalid number of positional arguments")
                 .context("cause", concat!("expected at most ", #num_max_positional, " positional argument", #plural))
         }
     };
@@ -619,14 +622,14 @@ fn generate_impl_filter_parameters(filter_parameters: &FilterParameters) -> Toke
         .filter(|parameter| parameter.is_keyword() && parameter.is_required())
         .map(|field| {
             let liquid_name = field.liquid_name();
-            quote!{ let #field = #field.ok_or_else(|| ::liquid::error::Error::with_msg(concat!("Expected named argument `", #liquid_name, "`")))?; }
+            quote!{ let #field = #field.ok_or_else(|| ::liquid_core::error::Error::with_msg(concat!("Expected named argument `", #liquid_name, "`")))?; }
         });
 
     quote! {
-        impl<'a> ::liquid::compiler::FilterParameters<'a> for #name {
+        impl<'a> ::liquid_core::compiler::FilterParameters<'a> for #name {
             type EvaluatedFilterParameters = #evaluated_name<'a>;
 
-            fn from_args(mut args: ::liquid::compiler::FilterArguments) -> ::liquid::error::Result<Self> {
+            fn from_args(mut args: ::liquid_core::compiler::FilterArguments) -> ::liquid_core::error::Result<Self> {
                 #(#construct_positional_fields)*
                 if let ::std::option::Option::Some(arg) = args.positional.next() {
                     return ::std::result::Result::Err(#too_many_args);
@@ -637,7 +640,7 @@ fn generate_impl_filter_parameters(filter_parameters: &FilterParameters) -> Toke
                 while let ::std::option::Option::Some(arg) = args.keyword.next() {
                     match arg.0 {
                         #(#match_keyword_parameters_arms)*
-                        keyword => return ::std::result::Result::Err(::liquid::error::Error::with_msg(format!("Unexpected named argument `{}`", keyword))),
+                        keyword => return ::std::result::Result::Err(::liquid_core::error::Error::with_msg(format!("Unexpected named argument `{}`", keyword))),
                     }
                 }
                 #(#unwrap_required_keyword_fields)*
@@ -645,7 +648,7 @@ fn generate_impl_filter_parameters(filter_parameters: &FilterParameters) -> Toke
                 Ok( #name { #comma_separated_field_names } )
             }
 
-            fn evaluate(&'a self, context: &'a ::liquid::interpreter::Context) -> ::liquid::error::Result<Self::EvaluatedFilterParameters> {
+            fn evaluate(&'a self, context: &'a ::liquid_core::interpreter::Context) -> ::liquid_core::error::Result<Self::EvaluatedFilterParameters> {
                #(#evaluate_fields)*
 
                 Ok( #evaluated_name { #comma_separated_field_names __phantom_data: ::std::marker::PhantomData } )
@@ -655,7 +658,7 @@ fn generate_impl_filter_parameters(filter_parameters: &FilterParameters) -> Toke
 }
 
 /// Generates `EvaluatedFilterParameters` struct.
-fn generate_evaluated_struct(filter_parameters: &FilterParameters) -> TokenStream {
+fn generate_evaluated_struct(filter_parameters: &FilterParameters<'_>) -> TokenStream {
     let FilterParameters {
         evaluated_name,
         fields,
@@ -665,13 +668,13 @@ fn generate_evaluated_struct(filter_parameters: &FilterParameters) -> TokenStrea
 
     let field_types = fields.parameters.iter().map(|field| {
         let ty = match &field.meta.ty {
-            FilterParameterType::Value => quote! {&'a ::liquid::value::ValueView},
+            FilterParameterType::Value => quote! {&'a ::liquid_core::value::ValueView},
             FilterParameterType::Integer => quote! { i32 },
             FilterParameterType::Float => quote! { f64 },
             FilterParameterType::Bool => quote! { bool },
-            FilterParameterType::DateTime => quote! { ::liquid::value::DateTime },
-            FilterParameterType::Date => quote! { ::liquid::value::Date },
-            FilterParameterType::Str => quote! { ::liquid::value::kstring::KStringCow<'a> },
+            FilterParameterType::DateTime => quote! { ::liquid_core::value::DateTime },
+            FilterParameterType::Date => quote! { ::liquid_core::value::Date },
+            FilterParameterType::Str => quote! { ::kstring::KStringCow<'a> },
         };
 
         if field.is_optional() {
@@ -692,13 +695,13 @@ fn generate_evaluated_struct(filter_parameters: &FilterParameters) -> TokenStrea
 }
 
 /// Constructs `ParameterReflection` for the given parameter.
-fn generate_parameter_reflection(field: &FilterParameter) -> TokenStream {
+fn generate_parameter_reflection(field: &FilterParameter<'_>) -> TokenStream {
     let name = field.liquid_name();
     let description = &field.meta.description.to_string();
     let is_optional = field.is_optional();
 
     quote! {
-        ::liquid::compiler::ParameterReflection {
+        ::liquid_core::compiler::ParameterReflection {
             name: #name,
             description: #description,
             is_optional: #is_optional,
@@ -707,7 +710,7 @@ fn generate_parameter_reflection(field: &FilterParameter) -> TokenStream {
 }
 
 /// Generates implementation of `FilterParametersReflection`.
-fn generate_impl_reflection(filter_parameters: &FilterParameters) -> TokenStream {
+fn generate_impl_reflection(filter_parameters: &FilterParameters<'_>) -> TokenStream {
     let FilterParameters { name, fields, .. } = filter_parameters;
 
     let kw_params_reflection = fields
@@ -723,12 +726,12 @@ fn generate_impl_reflection(filter_parameters: &FilterParameters) -> TokenStream
         .map(generate_parameter_reflection);
 
     quote! {
-        impl ::liquid::compiler::FilterParametersReflection for #name {
-            fn positional_parameters() -> &'static [::liquid::compiler::ParameterReflection] {
+        impl ::liquid_core::compiler::FilterParametersReflection for #name {
+            fn positional_parameters() -> &'static [::liquid_core::compiler::ParameterReflection] {
                 &[ #(#pos_params_reflection)* ]
             }
 
-            fn keyword_parameters() -> &'static [::liquid::compiler::ParameterReflection] {
+            fn keyword_parameters() -> &'static [::liquid_core::compiler::ParameterReflection] {
                 &[ #(#kw_params_reflection)* ]
             }
         }
@@ -736,7 +739,7 @@ fn generate_impl_reflection(filter_parameters: &FilterParameters) -> TokenStream
 }
 
 /// Helper function for `generate_impl_display`
-fn generate_access_positional_field_for_display(field: &FilterParameter) -> TokenStream {
+fn generate_access_positional_field_for_display(field: &FilterParameter<'_>) -> TokenStream {
     let rust_name = &field.name;
 
     if field.is_optional() {
@@ -751,7 +754,7 @@ fn generate_access_positional_field_for_display(field: &FilterParameter) -> Toke
 }
 
 /// Helper function for `generate_impl_display`
-fn generate_access_keyword_field_for_display(field: &FilterParameter) -> TokenStream {
+fn generate_access_keyword_field_for_display(field: &FilterParameter<'_>) -> TokenStream {
     let rust_name = &field.name;
     let liquid_name = field.liquid_name();
 
@@ -767,7 +770,7 @@ fn generate_access_keyword_field_for_display(field: &FilterParameter) -> TokenSt
 }
 
 /// Generates implementation of `Display`.
-fn generate_impl_display(filter_parameters: &FilterParameters) -> TokenStream {
+fn generate_impl_display(filter_parameters: &FilterParameters<'_>) -> TokenStream {
     let FilterParameters { name, fields, .. } = filter_parameters;
 
     let positional_fields = fields
@@ -790,9 +793,9 @@ fn generate_impl_display(filter_parameters: &FilterParameters) -> TokenStream {
 
                 let positional = positional
                     .iter()
-                    .filter_map(|p: &::std::option::Option<&::liquid::interpreter::Expression>| p.as_ref())
+                    .filter_map(|p: &::std::option::Option<&::liquid_core::interpreter::Expression>| p.as_ref())
                     .map(|p| p.to_string());
-                let keyword = keyword.iter().filter_map(|p: &(&str, ::std::option::Option<&::liquid::interpreter::Expression>)| match p.1 {
+                let keyword = keyword.iter().filter_map(|p: &(&str, ::std::option::Option<&::liquid_core::interpreter::Expression>)| match p.1 {
                     ::std::option::Option::Some(p1) => ::std::option::Option::Some(format!("{}: {}", p.0, p1)),
                     ::std::option::Option::None => ::std::option::Option::None,
                 });
diff --git a/crates/derive/src/lib.rs b/crates/derive/src/lib.rs
index ce23e2a..f765629 100644
--- a/crates/derive/src/lib.rs
+++ b/crates/derive/src/lib.rs
@@ -1,11 +1,8 @@
 //! Derive macros to aid in filter creation.
 
-extern crate liquid_compiler;
-extern crate liquid_error;
 extern crate proc_macro;
-extern crate proc_macro2;
-extern crate proc_quote;
-extern crate syn;
+
+use syn;
 
 mod filter;
 mod filter_parameters;
@@ -32,7 +29,7 @@ use proc_macro::TokenStream;
 ///
 /// `TYPE` will be either `Expression` or `Option<Expression>`, marking the
 /// parameter, respectively, as either required or optional. Note `Expression`
-/// here is the type `::liquid::interpreter::Expression`.
+/// here is the type `::liquid_core::interpreter::Expression`.
 ///
 /// Inside the `#[parameter(...)]` attribute there may be some information
 /// about the parameter, such as:
diff --git a/crates/derive/src/parse_filter/filter_reflection.rs b/crates/derive/src/parse_filter/filter_reflection.rs
index dd17fe3..010eb49 100644
--- a/crates/derive/src/parse_filter/filter_reflection.rs
+++ b/crates/derive/src/parse_filter/filter_reflection.rs
@@ -1,7 +1,7 @@
 use super::*;
 
 /// Generates implementation of `FilterReflection`.
-fn generate_reflection(filter_parser: &ParseFilter) -> Result<TokenStream> {
+fn generate_reflection(filter_parser: &ParseFilter<'_>) -> Result<TokenStream> {
     let ParseFilterMeta {
         filter_name,
         filter_description,
@@ -13,14 +13,14 @@ fn generate_reflection(filter_parser: &ParseFilter) -> Result<TokenStream> {
     let filter_description = filter_description.as_ref().map_err(|err| err.clone())?;
 
     let impl_filter_reflection =
-        filter_parser.generate_impl(quote! { ::liquid::compiler::FilterReflection });
+        filter_parser.generate_impl(quote! { ::liquid_core::compiler::FilterReflection });
 
     let (positional_parameters, keyword_parameters) = if let Some(parameters_struct_name) =
         parameters_struct_name
     {
         (
-            quote_spanned! {parameters_struct_name.span()=> <#parameters_struct_name as ::liquid::compiler::FilterParametersReflection>::positional_parameters() },
-            quote_spanned! {parameters_struct_name.span()=> <#parameters_struct_name as ::liquid::compiler::FilterParametersReflection>::keyword_parameters() },
+            quote_spanned! {parameters_struct_name.span()=> <#parameters_struct_name as ::liquid_core::compiler::FilterParametersReflection>::positional_parameters() },
+            quote_spanned! {parameters_struct_name.span()=> <#parameters_struct_name as ::liquid_core::compiler::FilterParametersReflection>::keyword_parameters() },
         )
     } else {
         (quote! { &[] }, quote! { &[] })
@@ -35,11 +35,11 @@ fn generate_reflection(filter_parser: &ParseFilter) -> Result<TokenStream> {
                 #filter_description
             }
 
-            fn positional_parameters(&self) -> &'static [::liquid::compiler::ParameterReflection] {
+            fn positional_parameters(&self) -> &'static [::liquid_core::compiler::ParameterReflection] {
                 #positional_parameters
             }
 
-            fn keyword_parameters(&self) -> &'static [::liquid::compiler::ParameterReflection] {
+            fn keyword_parameters(&self) -> &'static [::liquid_core::compiler::ParameterReflection] {
                 #keyword_parameters
             }
         }
diff --git a/crates/derive/src/parse_filter/mod.rs b/crates/derive/src/parse_filter/mod.rs
index 5615bc2..82c0e08 100644
--- a/crates/derive/src/parse_filter/mod.rs
+++ b/crates/derive/src/parse_filter/mod.rs
@@ -1,4 +1,4 @@
-use helpers::*;
+use crate::helpers::*;
 use proc_macro2::*;
 use proc_quote::*;
 use syn::*;
diff --git a/crates/derive/src/parse_filter/parse_filter.rs b/crates/derive/src/parse_filter/parse_filter.rs
index 46be383..2f4fd72 100644
--- a/crates/derive/src/parse_filter/parse_filter.rs
+++ b/crates/derive/src/parse_filter/parse_filter.rs
@@ -1,7 +1,7 @@
 use super::*;
 
 /// Generates implementation of `ParseFilter`.
-fn generate_parse_filter(filter_parser: &ParseFilter) -> Result<TokenStream> {
+fn generate_parse_filter(filter_parser: &ParseFilter<'_>) -> Result<TokenStream> {
     let ParseFilterMeta {
         parameters_struct_name,
         filter_struct_name,
@@ -10,11 +10,12 @@ fn generate_parse_filter(filter_parser: &ParseFilter) -> Result<TokenStream> {
 
     let filter_struct_name = filter_struct_name.as_ref().map_err(|err| err.clone())?;
 
-    let impl_parse_filter = filter_parser.generate_impl(quote! { ::liquid::compiler::ParseFilter });
+    let impl_parse_filter =
+        filter_parser.generate_impl(quote! { ::liquid_core::compiler::ParseFilter });
 
     if let Some(parameters_struct_name) = parameters_struct_name {
         let build_filter_parameters = quote_spanned! {parameters_struct_name.span()=>
-            let args = <#parameters_struct_name as ::liquid::compiler::FilterParameters>::from_args(args)?;
+            let args = <#parameters_struct_name as ::liquid_core::compiler::FilterParameters>::from_args(args)?;
         };
 
         let return_expr = quote_spanned! {filter_struct_name.span()=>
@@ -23,12 +24,12 @@ fn generate_parse_filter(filter_parser: &ParseFilter) -> Result<TokenStream> {
 
         Ok(quote! {
             #impl_parse_filter {
-                fn parse(&self, args: ::liquid::compiler::FilterArguments) -> ::liquid::error::Result<::std::boxed::Box<::liquid::compiler::Filter>> {
+                fn parse(&self, args: ::liquid_core::compiler::FilterArguments) -> ::liquid_core::error::Result<::std::boxed::Box<::liquid_core::compiler::Filter>> {
                     #build_filter_parameters
                     #return_expr
                 }
 
-                fn reflection(&self) -> &::liquid::compiler::FilterReflection {
+                fn reflection(&self) -> &::liquid_core::compiler::FilterReflection {
                     self
                 }
             }
@@ -39,20 +40,20 @@ fn generate_parse_filter(filter_parser: &ParseFilter) -> Result<TokenStream> {
         };
         Ok(quote! {
             #impl_parse_filter {
-                fn parse(&self, mut args: ::liquid::compiler::FilterArguments) -> ::liquid::error::Result<::std::boxed::Box<::liquid::compiler::Filter>> {
+                fn parse(&self, mut args: ::liquid_core::compiler::FilterArguments) -> ::liquid_core::error::Result<::std::boxed::Box<::liquid_core::compiler::Filter>> {
                     if let ::std::option::Option::Some(arg) = args.positional.next() {
-                        return ::std::result::Result::Err(::liquid::error::Error::with_msg("Invalid number of positional arguments")
+                        return ::std::result::Result::Err(::liquid_core::error::Error::with_msg("Invalid number of positional arguments")
                             .context("cause", concat!("expected at most 0 positional arguments"))
                         );
                     }
                     if let ::std::option::Option::Some(arg) = args.keyword.next() {
-                        return ::std::result::Result::Err(::liquid::error::Error::with_msg(format!("Unexpected named argument `{}`", arg.0)));
+                        return ::std::result::Result::Err(::liquid_core::error::Error::with_msg(format!("Unexpected named argument `{}`", arg.0)));
                     }
 
                     #return_expr
                 }
 
-                fn reflection(&self) -> &::liquid::compiler::FilterReflection {
+                fn reflection(&self) -> &::liquid_core::compiler::FilterReflection {
                     self
                 }
             }
diff --git a/crates/error/Cargo.toml b/crates/error/Cargo.toml
index 140c3ca..af76299 100644
--- a/crates/error/Cargo.toml
+++ b/crates/error/Cargo.toml
@@ -3,7 +3,7 @@ name = "liquid-error"
 version = "0.19.0"
 authors = ["Johann Hofmann <mail@johann-hofmann.com>"]
 description = "The liquid templating language for Rust"
-repository = "https://github.com/cobalt-org/liquid-rust/tree/master/liquid-error"
+repository = "https://github.com/cobalt-org/liquid-rust/tree/master/crate/error"
 documentation = "https://docs.rs/liquid-error"
 readme = "README.md"
 categories = ["template-engine"]
diff --git a/crates/error/src/error.rs b/crates/error/src/error.rs
index 71e074e..3a1edbf 100644
--- a/crates/error/src/error.rs
+++ b/crates/error/src/error.rs
@@ -6,7 +6,7 @@ use super::ErrorClone;
 use super::Trace;
 
 /// Convenience type alias for Liquid compiler errors
-pub type Result<T> = result::Result<T, Error>;
+pub type Result<T, E = Error> = result::Result<T, E>;
 
 type BoxedError = Box<dyn ErrorClone>;
 
diff --git a/crates/help-md/Cargo.toml b/crates/help-md/Cargo.toml
index 90ba2f4..e8c14bd 100644
--- a/crates/help-md/Cargo.toml
+++ b/crates/help-md/Cargo.toml
@@ -15,4 +15,4 @@ edition = "2018"
 azure-devops = { project = "cobalt-org", pipeline = "liquid-rust" }
 
 [dependencies]
-liquid = { version = "0.19", path = "../../" }
+liquid-core = { version = "0.19", path = "../core" }
diff --git a/crates/help-md/src/lib.rs b/crates/help-md/src/lib.rs
index f2ff426..3498889 100644
--- a/crates/help-md/src/lib.rs
+++ b/crates/help-md/src/lib.rs
@@ -7,7 +7,7 @@ pub trait Renderable {
     fn render(&self, stream: &mut dyn std::io::Write) -> Result<(), Box<dyn std::error::Error>>;
 }
 
-impl Renderable for dyn liquid::compiler::FilterReflection {
+impl Renderable for dyn liquid_core::FilterReflection {
     fn render_summary(
         &self,
         stream: &mut dyn std::io::Write,
@@ -55,7 +55,7 @@ impl Renderable for dyn liquid::compiler::FilterReflection {
     }
 }
 
-impl Renderable for dyn liquid::compiler::TagReflection {
+impl Renderable for dyn liquid_core::TagReflection {
     fn render_summary(
         &self,
         stream: &mut dyn std::io::Write,
@@ -81,7 +81,7 @@ impl Renderable for dyn liquid::compiler::TagReflection {
     }
 }
 
-impl Renderable for dyn liquid::compiler::BlockReflection {
+impl Renderable for dyn liquid_core::BlockReflection {
     fn render_summary(
         &self,
         stream: &mut dyn std::io::Write,
diff --git a/crates/interpreter/Cargo.toml b/crates/interpreter/Cargo.toml
index 5c9af65..475c419 100644
--- a/crates/interpreter/Cargo.toml
+++ b/crates/interpreter/Cargo.toml
@@ -3,7 +3,7 @@ name = "liquid-interpreter"
 version = "0.19.0"
 authors = ["Johann Hofmann <mail@johann-hofmann.com>"]
 description = "The liquid templating language for Rust"
-repository = "https://github.com/cobalt-org/liquid-rust/tree/master/liquid-interpreter"
+repository = "https://github.com/cobalt-org/liquid-rust/tree/master/crate/interpreter"
 documentation = "https://docs.rs/liquid-interpreter"
 readme = "README.md"
 categories = ["template-engine"]
diff --git a/crates/kstring/src/string.rs b/crates/kstring/src/string.rs
index 9cbc87d..263b51a 100644
--- a/crates/kstring/src/string.rs
+++ b/crates/kstring/src/string.rs
@@ -355,7 +355,7 @@ struct StringVisitor;
 impl<'de> serde::de::Visitor<'de> for StringVisitor {
     type Value = KString;
 
-    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
         formatter.write_str("a string")
     }
 
diff --git a/crates/value/Cargo.toml b/crates/value/Cargo.toml
index 0dfc4b8..5386d02 100644
--- a/crates/value/Cargo.toml
+++ b/crates/value/Cargo.toml
@@ -3,7 +3,7 @@ name = "liquid-value"
 version = "0.19.1"
 authors = ["Johann Hofmann <mail@johann-hofmann.com>"]
 description = "The liquid templating language for Rust"
-repository = "https://github.com/cobalt-org/liquid-rust/tree/master/liquid-value"
+repository = "https://github.com/cobalt-org/liquid-rust/tree/master/crate/value"
 documentation = "https://docs.rs/liquid-value"
 readme = "README.md"
 categories = ["template-engine"]
diff --git a/crates/value/src/lib.rs b/crates/value/src/lib.rs
index 1baa358..ca8ad9e 100644
--- a/crates/value/src/lib.rs
+++ b/crates/value/src/lib.rs
@@ -23,16 +23,6 @@ mod view;
 
 pub mod map;
 
-/// Liquid Processing Errors.
-pub mod error {
-    pub use liquid_error::*;
-}
-
-/// String-type optimized for `Value`
-pub mod kstring {
-    pub use kstring::*;
-}
-
 pub use crate::array::*;
 pub use crate::date::*;
 pub use crate::display::*;
diff --git a/crates/value/src/path.rs b/crates/value/src/path.rs
index 009cfc0..3e10ef1 100644
--- a/crates/value/src/path.rs
+++ b/crates/value/src/path.rs
@@ -83,7 +83,7 @@ impl<'s> fmt::Display for Path<'s> {
 
 /// Iterate over indexes in a `Value`'s `Path`.
 #[derive(Debug)]
-pub struct PathIter<'i, 's: 'i>(slice::Iter<'i, ScalarCow<'s>>);
+pub struct PathIter<'i, 's>(slice::Iter<'i, ScalarCow<'s>>);
 
 impl<'i, 's: 'i> Iterator for PathIter<'i, 's> {
     type Item = &'i ScalarCow<'s>;
diff --git a/crates/value/src/ser.rs b/crates/value/src/ser.rs
index 1a1d20b..941758d 100644
--- a/crates/value/src/ser.rs
+++ b/crates/value/src/ser.rs
@@ -8,7 +8,6 @@ use serde::{self, Serialize};
 use super::Object;
 use super::Scalar;
 use super::Value;
-use crate::error;
 
 /// Convert a `T` into `liquid_value::Value`.
 ///
@@ -19,7 +18,7 @@ use crate::error;
 /// let value = liquid_value::to_value(s).unwrap();
 /// assert_eq!(value, liquid_value::Value::scalar(s));
 /// ```
-pub fn to_value<T>(value: T) -> Result<Value, error::Error>
+pub fn to_value<T>(value: T) -> Result<Value, liquid_error::Error>
 where
     T: Serialize,
 {
@@ -27,7 +26,7 @@ where
 }
 
 /// Convert a `T` into `liquid_value::Object`.
-pub fn to_object<T>(value: T) -> Result<Object, error::Error>
+pub fn to_object<T>(value: T) -> Result<Object, liquid_error::Error>
 where
     T: Serialize,
 {
@@ -43,7 +42,7 @@ where
 /// let value = liquid_value::to_scalar(s).unwrap();
 /// assert_eq!(value, liquid_value::Scalar::new(s));
 /// ```
-pub fn to_scalar<T>(value: T) -> Result<Scalar, error::Error>
+pub fn to_scalar<T>(value: T) -> Result<Scalar, liquid_error::Error>
 where
     T: Serialize,
 {
@@ -51,7 +50,7 @@ where
 }
 
 #[derive(Debug)]
-struct SerError(error::Error);
+struct SerError(liquid_error::Error);
 
 impl fmt::Display for SerError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -74,7 +73,7 @@ impl serde::ser::Error for SerError {
     where
         T: fmt::Display,
     {
-        SerError(error::Error::with_msg(format!("{}", msg)))
+        SerError(liquid_error::Error::with_msg(format!("{}", msg)))
     }
 }
 
@@ -373,11 +372,11 @@ impl serde::ser::SerializeTupleStruct for SerializeVec {
 struct ObjectSerializer;
 
 fn object_cannot_be_a_scalar() -> SerError {
-    SerError(error::Error::with_msg("Object cannot be a scalar."))
+    SerError(liquid_error::Error::with_msg("Object cannot be a scalar."))
 }
 
 fn object_cannot_be_an_array() -> SerError {
-    SerError(error::Error::with_msg("Object cannot be an array."))
+    SerError(liquid_error::Error::with_msg("Object cannot be an array."))
 }
 
 impl serde::Serializer for ObjectSerializer {
@@ -692,7 +691,7 @@ impl<O: From<Object>> serde::ser::SerializeMap for SerializeMap<O> {
 struct MapKeySerializer;
 
 fn key_must_be_a_string() -> SerError {
-    SerError(error::Error::with_msg("Key must be a string."))
+    SerError(liquid_error::Error::with_msg("Key must be a string."))
 }
 
 impl serde::Serializer for MapKeySerializer {
@@ -903,7 +902,7 @@ impl<O: From<Object>> serde::ser::SerializeStructVariant for SerializeStructVari
 struct ScalarSerializer;
 
 fn scalar_must_be_a_string() -> SerError {
-    SerError(error::Error::with_msg("Scalar must be a string."))
+    SerError(liquid_error::Error::with_msg("Scalar must be a string."))
 }
 
 impl serde::Serializer for ScalarSerializer {
@@ -1092,6 +1091,6 @@ impl serde::Serializer for ScalarSerializer {
 #[inline]
 fn serialize_as_i32<T: num_traits::cast::NumCast>(value: T) -> Result<Scalar, SerError> {
     let value = num_traits::cast::cast::<T, i32>(value)
-        .ok_or_else(|| SerError(error::Error::with_msg("Cannot fit number")))?;
+        .ok_or_else(|| SerError(liquid_error::Error::with_msg("Cannot fit number")))?;
     Ok(Scalar::new(value))
 }
diff --git a/crates/value/src/view.rs b/crates/value/src/view.rs
index 704fb5f..f45e1e0 100644
--- a/crates/value/src/view.rs
+++ b/crates/value/src/view.rs
@@ -126,7 +126,7 @@ pub struct ValueViewCmp<'v>(&'v dyn ValueView);
 
 impl<'v> ValueViewCmp<'v> {
     /// `Value` comparison semantics for types implementing `ValueView`.
-    pub fn new(v: &dyn ValueView) -> ValueViewCmp {
+    pub fn new(v: &dyn ValueView) -> ValueViewCmp<'_> {
         ValueViewCmp(v)
     }
 }
diff --git a/src/filters/extra/date.rs b/src/filters/extra/date.rs
index 0d69d46..4ad7708 100644
--- a/src/filters/extra/date.rs
+++ b/src/filters/extra/date.rs
@@ -1,11 +1,13 @@
 use chrono::FixedOffset;
-use filters::invalid_input;
-use liquid_compiler::{Filter, FilterParameters};
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_interpreter::Expression;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+use liquid_core::{Value, ValueView};
+
+use crate::filters::invalid_input;
 
 // liquid-rust proprietary
 
@@ -37,7 +39,7 @@ struct DateInTzFilter {
 }
 
 impl Filter for DateInTzFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let date = input
@@ -63,14 +65,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
@@ -79,14 +81,14 @@ mod tests {
             failed!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            ::liquid::compiler::ParseFilter::parse(&$a, args)
-                .and_then(|filter| ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context))
+            ::liquid_core::compiler::ParseFilter::parse(&$a, args)
+                .and_then(|filter| ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context))
                 .unwrap_err()
         }};
     }
diff --git a/src/filters/extra/pluralize.rs b/src/filters/extra/pluralize.rs
index a348128..32e98ea 100644
--- a/src/filters/extra/pluralize.rs
+++ b/src/filters/extra/pluralize.rs
@@ -1,10 +1,12 @@
-use filters::invalid_input;
-use liquid_compiler::{Filter, FilterParameters};
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_interpreter::Expression;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+use liquid_core::{Value, ValueView};
+
+use crate::filters::invalid_input;
 
 // shopify-specific
 
@@ -33,7 +35,7 @@ struct PluralizeFilter {
 }
 
 impl Filter for PluralizeFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let n = input
@@ -59,14 +61,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
diff --git a/src/filters/jekyll/array.rs b/src/filters/jekyll/array.rs
index b6bbf85..154dcd3 100644
--- a/src/filters/jekyll/array.rs
+++ b/src/filters/jekyll/array.rs
@@ -1,13 +1,14 @@
 use std::fmt::Write;
 
-use liquid_compiler::{Filter, FilterParameters};
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_interpreter::Expression;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+use liquid_core::{Value, ValueView};
 
-use filters::invalid_input;
+use crate::filters::invalid_input;
 
 #[derive(Debug, FilterParameters)]
 struct PushArgs {
@@ -32,7 +33,7 @@ struct PushFilter {
 }
 
 impl Filter for PushFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let element = args.element.to_value();
@@ -59,7 +60,7 @@ pub struct Pop;
 struct PopFilter;
 
 impl Filter for PopFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let mut array = input
             .to_value()
             .into_array()
@@ -93,7 +94,7 @@ struct UnshiftFilter {
 }
 
 impl Filter for UnshiftFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let element = args.element.to_value();
@@ -120,7 +121,7 @@ pub struct Shift;
 struct ShiftFilter;
 
 impl Filter for ShiftFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let mut array = input
             .to_value()
             .into_array()
@@ -160,7 +161,7 @@ struct ArrayToSentenceStringFilter {
 }
 
 impl Filter for ArrayToSentenceStringFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let connector = args.connector.unwrap_or("and".into());
@@ -200,14 +201,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
diff --git a/src/filters/jekyll/slugify.rs b/src/filters/jekyll/slugify.rs
index f2633ea..c854af4 100644
--- a/src/filters/jekyll/slugify.rs
+++ b/src/filters/jekyll/slugify.rs
@@ -1,10 +1,11 @@
 use deunicode;
-use liquid_compiler::{Filter, FilterParameters};
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_interpreter::Expression;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+use liquid_core::{Value, ValueView};
 use regex::Regex;
 
 #[derive(PartialEq)]
@@ -66,7 +67,7 @@ struct SlugifyFilter {
 }
 
 impl Filter for SlugifyFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let s = input.to_kstr();
@@ -105,14 +106,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
diff --git a/src/filters/mod.rs b/src/filters/mod.rs
index 5573684..d53ba0a 100644
--- a/src/filters/mod.rs
+++ b/src/filters/mod.rs
@@ -1,4 +1,4 @@
-use liquid_error::Error;
+use liquid_core::Error;
 
 pub mod std;
 
diff --git a/src/filters/std/array.rs b/src/filters/std/array.rs
index b338672..c476895 100644
--- a/src/filters/std/array.rs
+++ b/src/filters/std/array.rs
@@ -1,12 +1,16 @@
-use filters::{invalid_argument, invalid_input};
-use liquid_compiler::{Filter, FilterParameters};
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_interpreter::Expression;
-use liquid_value::{Value, ValueView, ValueViewCmp};
 use std::cmp;
 
+use liquid_core::value::ValueViewCmp;
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+use liquid_core::{Value, ValueView};
+
+use crate::filters::{invalid_argument, invalid_input};
+
 fn as_sequence<'k>(input: &'k dyn ValueView) -> Box<dyn Iterator<Item = &'k dyn ValueView> + 'k> {
     if let Some(array) = input.as_array() {
         array.values()
@@ -43,7 +47,7 @@ struct JoinFilter {
 }
 
 impl Filter for JoinFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let separator = args.separator.unwrap_or_else(|| " ".into());
@@ -116,7 +120,7 @@ fn safe_property_getter<'a>(value: &'a Value, property: &str) -> &'a dyn ValueVi
 }
 
 impl Filter for SortFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input: Vec<_> = as_sequence(input).collect();
@@ -158,7 +162,7 @@ struct SortNaturalFilter {
 }
 
 impl Filter for SortNaturalFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input: Vec<_> = as_sequence(input).collect();
@@ -219,7 +223,7 @@ struct WhereFilter {
 }
 
 impl Filter for WhereFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
         let property: &str = &args.property;
         let target_value: Option<&dyn ValueView> = args.target_value;
@@ -245,7 +249,7 @@ impl Filter for WhereFilter {
                 .filter(|object| {
                     object
                         .get(property)
-                        .map_or(false, |v| v.query_state(liquid_value::State::Truthy))
+                        .map_or(false, |v| v.query_state(liquid_core::value::State::Truthy))
                 })
                 .map(|object| object.to_value())
                 .collect(),
@@ -281,7 +285,7 @@ pub struct Uniq;
 struct UniqFilter;
 
 impl Filter for UniqFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         // TODO(#267) optional property parameter
 
         let array = input
@@ -314,7 +318,7 @@ pub struct Reverse;
 struct ReverseFilter;
 
 impl Filter for ReverseFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let mut array: Vec<_> = input
             .as_array()
             .ok_or_else(|| invalid_input("Array expected"))?
@@ -352,7 +356,7 @@ struct MapFilter {
 }
 
 impl Filter for MapFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let array = input
@@ -388,7 +392,7 @@ struct CompactFilter {
 }
 
 impl Filter for CompactFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let array = input
@@ -444,7 +448,7 @@ struct ConcatFilter {
 }
 
 impl Filter for ConcatFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input
@@ -477,7 +481,7 @@ pub struct First;
 struct FirstFilter;
 
 impl Filter for FirstFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         match *input {
             Value::Scalar(ref x) => {
                 let c = x
@@ -507,7 +511,7 @@ pub struct Last;
 struct LastFilter;
 
 impl Filter for LastFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         match *input {
             Value::Scalar(ref x) => {
                 let c = x
@@ -534,14 +538,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
@@ -550,14 +554,14 @@ mod tests {
             failed!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            ::liquid::compiler::ParseFilter::parse(&$a, args)
-                .and_then(|filter| ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context))
+            ::liquid_core::compiler::ParseFilter::parse(&$a, args)
+                .and_then(|filter| ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context))
                 .unwrap_err()
         }};
     }
diff --git a/src/filters/std/date.rs b/src/filters/std/date.rs
index 160a582..fecd3d9 100644
--- a/src/filters/std/date.rs
+++ b/src/filters/std/date.rs
@@ -1,9 +1,10 @@
-use liquid_compiler::{Filter, FilterParameters};
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_interpreter::Expression;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+use liquid_core::{Value, ValueView};
 
 #[derive(Debug, FilterParameters)]
 struct DateArgs {
@@ -28,7 +29,7 @@ struct DateFilter {
 }
 
 impl Filter for DateFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let date = input.as_scalar().and_then(|s| s.to_date_time());
@@ -51,14 +52,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
@@ -67,14 +68,14 @@ mod tests {
             failed!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            ::liquid::compiler::ParseFilter::parse(&$a, args)
-                .and_then(|filter| ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context))
+            ::liquid_core::compiler::ParseFilter::parse(&$a, args)
+                .and_then(|filter| ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context))
                 .unwrap_err()
         }};
     }
diff --git a/src/filters/std/html.rs b/src/filters/std/html.rs
index 4f416ad..7fa46ca 100644
--- a/src/filters/std/html.rs
+++ b/src/filters/std/html.rs
@@ -1,8 +1,7 @@
-use liquid_compiler::Filter;
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Result;
+use liquid_core::{Display_filter, Filter, FilterReflection, ParseFilter};
+use liquid_core::{Value, ValueView};
 use regex::Regex;
 
 /// Returns the number of already escaped characters.
@@ -76,7 +75,7 @@ pub struct Escape;
 struct EscapeFilter;
 
 impl Filter for EscapeFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         escape(input, false)
     }
 }
@@ -94,7 +93,7 @@ pub struct EscapeOnce;
 struct EscapeOnceFilter;
 
 impl Filter for EscapeOnceFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         escape(input, true)
     }
 }
@@ -121,7 +120,7 @@ static MATCHERS: once_cell::sync::Lazy<[Regex; 4]> = once_cell::sync::Lazy::new(
 });
 
 impl Filter for StripHtmlFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let input = input.to_kstr().into_string();
 
         let result = MATCHERS.iter().fold(input, |acc, matcher| {
@@ -144,7 +143,7 @@ pub struct NewlineToBr;
 struct NewlineToBrFilter;
 
 impl Filter for NewlineToBrFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         // TODO handle windows line endings
         let input = input.to_kstr();
         Ok(Value::scalar(input.replace("\n", "<br />\n")))
@@ -161,14 +160,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
@@ -177,14 +176,14 @@ mod tests {
             failed!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            ::liquid::compiler::ParseFilter::parse(&$a, args)
-                .and_then(|filter| ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context))
+            ::liquid_core::compiler::ParseFilter::parse(&$a, args)
+                .and_then(|filter| ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context))
                 .unwrap_err()
         }};
     }
diff --git a/src/filters/std/math.rs b/src/filters/std/math.rs
index 4b05c6c..1a9392d 100644
--- a/src/filters/std/math.rs
+++ b/src/filters/std/math.rs
@@ -1,10 +1,12 @@
-use filters::{invalid_argument, invalid_input};
-use liquid_compiler::{Filter, FilterParameters};
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_interpreter::Expression;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+use liquid_core::{Value, ValueView};
+
+use crate::filters::{invalid_argument, invalid_input};
 
 #[derive(Clone, ParseFilter, FilterReflection)]
 #[filter(
@@ -19,7 +21,7 @@ pub struct Abs;
 struct AbsFilter;
 
 impl Filter for AbsFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         match *input {
             Value::Scalar(ref s) => s
                 .to_integer()
@@ -54,7 +56,7 @@ struct AtLeastFilter {
 }
 
 impl Filter for AtLeastFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input
@@ -103,7 +105,7 @@ struct AtMostFilter {
 }
 
 impl Filter for AtMostFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input
@@ -152,7 +154,7 @@ struct PlusFilter {
 }
 
 impl Filter for PlusFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input
@@ -201,7 +203,7 @@ struct MinusFilter {
 }
 
 impl Filter for MinusFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input
@@ -250,7 +252,7 @@ struct TimesFilter {
 }
 
 impl Filter for TimesFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input
@@ -299,7 +301,7 @@ struct DividedByFilter {
 }
 
 impl Filter for DividedByFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input
@@ -348,7 +350,7 @@ struct ModuloFilter {
 }
 
 impl Filter for ModuloFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input
@@ -400,7 +402,7 @@ struct RoundFilter {
 }
 
 impl Filter for RoundFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let n = args.decimal_places.unwrap_or(0);
@@ -437,7 +439,7 @@ pub struct Ceil;
 struct CeilFilter;
 
 impl Filter for CeilFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let n = input
             .as_scalar()
             .and_then(|s| s.to_float())
@@ -459,7 +461,7 @@ pub struct Floor;
 struct FloorFilter;
 
 impl Filter for FloorFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let n = input
             .as_scalar()
             .and_then(|s| s.to_float())
@@ -478,14 +480,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
@@ -494,14 +496,14 @@ mod tests {
             failed!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            ::liquid::compiler::ParseFilter::parse(&$a, args)
-                .and_then(|filter| ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context))
+            ::liquid_core::compiler::ParseFilter::parse(&$a, args)
+                .and_then(|filter| ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context))
                 .unwrap_err()
         }};
     }
diff --git a/src/filters/std/mod.rs b/src/filters/std/mod.rs
index 7156026..4c29854 100644
--- a/src/filters/std/mod.rs
+++ b/src/filters/std/mod.rs
@@ -1,9 +1,10 @@
-use liquid_compiler::{Filter, FilterParameters};
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_interpreter::Expression;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+use liquid_core::{Value, ValueView};
 
 mod array;
 mod date;
@@ -42,7 +43,7 @@ pub struct Size;
 struct SizeFilter;
 
 impl Filter for SizeFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         match *input {
             Value::Scalar(ref x) => Ok(Value::scalar(x.to_kstr().len() as i32)),
             Value::Array(ref x) => Ok(Value::scalar(x.len() as i32)),
@@ -75,10 +76,10 @@ struct DefaultFilter {
 }
 
 impl Filter for DefaultFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
-        if input.query_state(liquid_value::State::DefaultValue) {
+        if input.query_state(liquid_core::value::State::DefaultValue) {
             Ok(args.default.to_value())
         } else {
             Ok(input.clone())
@@ -90,21 +91,21 @@ impl Filter for DefaultFilter {
 mod tests {
 
     use super::*;
-    use liquid_value::Object;
+    use liquid_core::Object;
 
     macro_rules! unit {
         ($a:ident, $b:expr) => {{
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
diff --git a/src/filters/std/slice.rs b/src/filters/std/slice.rs
index 00a0b1d..b560e6a 100644
--- a/src/filters/std/slice.rs
+++ b/src/filters/std/slice.rs
@@ -1,12 +1,14 @@
 use std::cmp;
 
-use filters::invalid_argument;
-use liquid_compiler::{Filter, FilterParameters};
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_interpreter::Expression;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+use liquid_core::{Value, ValueView};
+
+use crate::filters::invalid_argument;
 
 fn canonicalize_slice(
     slice_offset: isize,
@@ -60,7 +62,7 @@ struct SliceFilter {
 }
 
 impl Filter for SliceFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let offset = args.offset as isize;
@@ -95,14 +97,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
@@ -111,14 +113,14 @@ mod tests {
             failed!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            ::liquid::compiler::ParseFilter::parse(&$a, args)
-                .and_then(|filter| ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context))
+            ::liquid_core::compiler::ParseFilter::parse(&$a, args)
+                .and_then(|filter| ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context))
                 .unwrap_err()
         }};
     }
diff --git a/src/filters/std/string/case.rs b/src/filters/std/string/case.rs
index f8c1092..97bdca1 100644
--- a/src/filters/std/string/case.rs
+++ b/src/filters/std/string/case.rs
@@ -1,8 +1,7 @@
-use liquid_compiler::Filter;
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Result;
+use liquid_core::{Display_filter, Filter, FilterReflection, ParseFilter};
+use liquid_core::{Value, ValueView};
 
 #[derive(Clone, ParseFilter, FilterReflection)]
 #[filter(
@@ -17,7 +16,7 @@ pub struct Downcase;
 struct DowncaseFilter;
 
 impl Filter for DowncaseFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let s = input.to_kstr();
         Ok(Value::scalar(s.to_lowercase()))
     }
@@ -36,7 +35,7 @@ pub struct Upcase;
 struct UpcaseFilter;
 
 impl Filter for UpcaseFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let s = input.to_kstr();
         Ok(Value::scalar(s.to_uppercase()))
     }
@@ -55,7 +54,7 @@ pub struct Capitalize;
 struct CapitalizeFilter;
 
 impl Filter for CapitalizeFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let s = input.to_kstr().to_owned();
         let mut chars = s.chars();
         let capitalized = match chars.next() {
@@ -77,14 +76,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
diff --git a/src/filters/std/string/mod.rs b/src/filters/std/string/mod.rs
index aaf98bc..8217159 100644
--- a/src/filters/std/string/mod.rs
+++ b/src/filters/std/string/mod.rs
@@ -1,9 +1,10 @@
-use liquid_compiler::{Filter, FilterParameters};
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_interpreter::Expression;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+use liquid_core::{Value, ValueView};
 
 pub mod case;
 pub mod operate;
@@ -36,7 +37,7 @@ struct SplitFilter {
 }
 
 impl Filter for SplitFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input.to_kstr();
@@ -61,14 +62,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
@@ -77,14 +78,14 @@ mod tests {
             failed!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            ::liquid::compiler::ParseFilter::parse(&$a, args)
-                .and_then(|filter| ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context))
+            ::liquid_core::compiler::ParseFilter::parse(&$a, args)
+                .and_then(|filter| ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context))
                 .unwrap_err()
         }};
     }
diff --git a/src/filters/std/string/operate.rs b/src/filters/std/string/operate.rs
index b655892..cd47267 100644
--- a/src/filters/std/string/operate.rs
+++ b/src/filters/std/string/operate.rs
@@ -1,9 +1,10 @@
-use liquid_compiler::{Filter, FilterParameters};
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_interpreter::Expression;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+use liquid_core::{Value, ValueView};
 
 #[derive(Debug, FilterParameters)]
 struct ReplaceArgs {
@@ -33,7 +34,7 @@ struct ReplaceFilter {
 }
 
 impl Filter for ReplaceFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input.to_kstr();
@@ -74,7 +75,7 @@ struct ReplaceFirstFilter {
 }
 
 impl Filter for ReplaceFirstFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input.to_kstr();
@@ -116,7 +117,7 @@ struct RemoveFilter {
 }
 
 impl Filter for RemoveFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input.to_kstr();
@@ -148,7 +149,7 @@ struct RemoveFirstFilter {
 }
 
 impl Filter for RemoveFirstFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input.to_kstr();
@@ -182,7 +183,7 @@ struct AppendFilter {
 }
 
 impl Filter for AppendFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let mut input = input.to_kstr().into_string();
@@ -215,7 +216,7 @@ struct PrependFilter {
 }
 
 impl Filter for PrependFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let input = input.to_kstr();
@@ -236,14 +237,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
diff --git a/src/filters/std/string/strip.rs b/src/filters/std/string/strip.rs
index 5260639..675013a 100644
--- a/src/filters/std/string/strip.rs
+++ b/src/filters/std/string/strip.rs
@@ -1,8 +1,7 @@
-use liquid_compiler::Filter;
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Result;
+use liquid_core::{Display_filter, Filter, FilterReflection, ParseFilter};
+use liquid_core::{Value, ValueView};
 
 /// Removes all whitespace (tabs, spaces, and newlines) from both the left and right side of a
 /// string.
@@ -24,7 +23,7 @@ pub struct Strip;
 struct StripFilter;
 
 impl Filter for StripFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let input = input.to_kstr();
         Ok(Value::scalar(input.trim().to_owned()))
     }
@@ -49,7 +48,7 @@ pub struct Lstrip;
 struct LstripFilter;
 
 impl Filter for LstripFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let input = input.to_kstr();
         Ok(Value::scalar(input.trim_start().to_owned()))
     }
@@ -74,7 +73,7 @@ pub struct Rstrip;
 struct RstripFilter;
 
 impl Filter for RstripFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let input = input.to_kstr();
         Ok(Value::scalar(input.trim_end().to_owned()))
     }
@@ -93,7 +92,7 @@ pub struct StripNewlines;
 struct StripNewlinesFilter;
 
 impl Filter for StripNewlinesFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         let input = input.to_kstr();
         Ok(Value::scalar(
             input
@@ -114,14 +113,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
@@ -130,14 +129,14 @@ mod tests {
             failed!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            ::liquid::compiler::ParseFilter::parse(&$a, args)
-                .and_then(|filter| ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context))
+            ::liquid_core::compiler::ParseFilter::parse(&$a, args)
+                .and_then(|filter| ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context))
                 .unwrap_err()
         }};
     }
diff --git a/src/filters/std/string/truncate.rs b/src/filters/std/string/truncate.rs
index ec8ac0b..89ed304 100644
--- a/src/filters/std/string/truncate.rs
+++ b/src/filters/std/string/truncate.rs
@@ -1,12 +1,13 @@
 use std::cmp;
 
 use itertools;
-use liquid_compiler::{Filter, FilterParameters};
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_interpreter::Expression;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
+use liquid_core::{Value, ValueView};
 use unicode_segmentation::UnicodeSegmentation;
 
 #[derive(Debug, FilterParameters)]
@@ -67,7 +68,7 @@ struct TruncateFilter {
 }
 
 impl Filter for TruncateFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let lenght = args.lenght.unwrap_or(50) as usize;
@@ -125,7 +126,7 @@ struct TruncateWordsFilter {
 }
 
 impl Filter for TruncateWordsFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let words = args.lenght.unwrap_or(50) as usize;
@@ -157,14 +158,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
@@ -173,14 +174,14 @@ mod tests {
             failed!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            ::liquid::compiler::ParseFilter::parse(&$a, args)
-                .and_then(|filter| ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context))
+            ::liquid_core::compiler::ParseFilter::parse(&$a, args)
+                .and_then(|filter| ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context))
                 .unwrap_err()
         }};
     }
diff --git a/src/filters/std/url.rs b/src/filters/std/url.rs
index 30230b3..2652d83 100644
--- a/src/filters/std/url.rs
+++ b/src/filters/std/url.rs
@@ -1,12 +1,12 @@
-use filters::invalid_input;
-use liquid_compiler::Filter;
-use liquid_derive::*;
-use liquid_error::Result;
-use liquid_interpreter::Context;
-use liquid_value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Result;
+use liquid_core::{Display_filter, Filter, FilterReflection, ParseFilter};
+use liquid_core::{Value, ValueView};
 use url::percent_encoding;
 use url::percent_encoding::EncodeSet;
 
+use crate::filters::invalid_input;
+
 #[derive(Clone)]
 struct UrlEncodeSet(String);
 
@@ -48,7 +48,7 @@ static URL_ENCODE_SET: once_cell::sync::Lazy<UrlEncodeSet> =
     once_cell::sync::Lazy::new(|| UrlEncodeSet("".to_owned()));
 
 impl Filter for UrlEncodeFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         if input.is_nil() {
             return Ok(Value::Nil);
         }
@@ -74,7 +74,7 @@ pub struct UrlDecode;
 struct UrlDecodeFilter;
 
 impl Filter for UrlDecodeFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         if input.is_nil() {
             return Ok(Value::Nil);
         }
@@ -99,14 +99,14 @@ mod tests {
             unit!($a, $b, )
         }};
         ($a:ident, $b:expr, $($c:expr),*) => {{
-            let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+            let positional = Box::new(vec![$(::liquid_core::interpreter::Expression::Literal($c)),*].into_iter());
             let keyword = Box::new(Vec::new().into_iter());
-            let args = ::liquid::compiler::FilterArguments { positional, keyword };
+            let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-            let context = ::liquid::interpreter::Context::default();
+            let context = ::liquid_core::interpreter::Context::default();
 
-            let filter = ::liquid::compiler::ParseFilter::parse(&$a, args).unwrap();
-            ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+            let filter = ::liquid_core::compiler::ParseFilter::parse(&$a, args).unwrap();
+            ::liquid_core::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
         }};
     }
 
diff --git a/src/lib.rs b/src/lib.rs
index 0396466..6f93539 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,69 +13,30 @@
 //!     .build().unwrap()
 //!     .parse("Liquid! {{num | minus: 2}}").unwrap();
 //!
-//! let mut globals = liquid::value::Object::new();
-//! globals.insert("num".into(), liquid::value::Value::scalar(4f64));
+//! let mut globals = liquid::object!({
+//!     "num": 4f64
+//! });
 //!
 //! let output = template.render(&globals).unwrap();
 //! assert_eq!(output, "Liquid! 2".to_string());
 //! ```
 
-extern crate chrono;
-extern crate deunicode;
-extern crate itertools;
-extern crate once_cell;
-extern crate regex;
-extern crate unicode_segmentation;
-extern crate url;
-
-#[cfg(feature = "serde")]
-extern crate serde;
-#[cfg(test)]
-extern crate serde_yaml;
-
-extern crate liquid_compiler;
-extern crate liquid_derive;
-extern crate liquid_error;
-extern crate liquid_interpreter;
-extern crate liquid_value;
-
 mod parser;
 mod reflection;
 mod template;
 
-/// Allows `liquid-derive` macros to work inside this crate.
-///
-/// This is necessary because paths to liquid items will
-/// start with `::liquid` in those macros.
-mod liquid {
-    pub use *;
-}
-
-pub mod compiler {
-    pub use liquid_compiler::*;
-}
-pub mod error {
-    pub use liquid_error::*;
-}
-pub mod interpreter {
-    pub use liquid_interpreter::*;
-}
-pub mod value {
-    pub use liquid_value::*;
-}
-pub mod derive {
-    pub use liquid_derive::*;
-}
-
 pub mod filters;
 pub mod partials;
 pub mod tags;
 
-pub use liquid_error::Error;
-pub use parser::*;
-pub use reflection::*;
-pub use template::*;
-pub use value::ObjectView;
+pub use crate::parser::*;
+pub use crate::reflection::*;
+pub use crate::template::*;
+pub use liquid_core::object;
+pub use liquid_core::to_object;
+pub use liquid_core::Error;
+pub use liquid_core::Object;
+pub use liquid_core::{ObjectView, ValueView};
 
 #[macro_use]
 extern crate doc_comment;
diff --git a/src/parser.rs b/src/parser.rs
index ced5851..969c3ae 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -3,15 +3,15 @@ use std::io::prelude::Read;
 use std::path;
 use std::sync;
 
-use liquid_compiler as compiler;
-use liquid_error::{Result, ResultLiquidExt, ResultLiquidReplaceExt};
-use liquid_interpreter as interpreter;
+use liquid_core::compiler;
+use liquid_core::error::{Result, ResultLiquidExt, ResultLiquidReplaceExt};
+use liquid_core::interpreter;
 
 use super::Template;
-use filters;
-use partials;
-use reflection;
-use tags;
+use crate::filters;
+use crate::partials;
+use crate::reflection;
+use crate::tags;
 
 /// Storage for partial-templates.
 ///
@@ -276,7 +276,7 @@ impl Parser {
     ///     .build().unwrap()
     ///     .parse("Liquid!").unwrap();
     ///
-    /// let globals = liquid::value::Object::new();
+    /// let globals = liquid::Object::new();
     /// let output = template.render(&globals).unwrap();
     /// assert_eq!(output, "Liquid!".to_string());
     /// ```
@@ -307,8 +307,9 @@ impl Parser {
     ///     .build().unwrap()
     ///     .parse_file("path/to/template.txt").unwrap();
     ///
-    /// let mut globals = liquid::value::Object::new();
-    /// globals.insert("data".into(), liquid::value::Value::scalar(4f64));
+    /// let globals = liquid::object!({
+    ///     "data": 4f64,
+    /// });
     /// let output = template.render(&globals).unwrap();
     /// assert_eq!(output, "Liquid! 4\n".to_string());
     /// ```
diff --git a/src/partials/eager.rs b/src/partials/eager.rs
index dbb470b..2819f09 100644
--- a/src/partials/eager.rs
+++ b/src/partials/eager.rs
@@ -2,13 +2,13 @@ use std::collections::HashMap;
 use std::fmt;
 use std::sync;
 
-use liquid_compiler;
-use liquid_compiler::Language;
-use liquid_error::Error;
-use liquid_error::Result;
-use liquid_interpreter;
-use liquid_interpreter::PartialStore;
-use liquid_interpreter::Renderable;
+use liquid_core::compiler;
+use liquid_core::compiler::Language;
+use liquid_core::error::Error;
+use liquid_core::error::Result;
+use liquid_core::interpreter;
+use liquid_core::interpreter::PartialStore;
+use liquid_core::interpreter::Renderable;
 
 use super::PartialCompiler;
 use super::PartialSource;
@@ -88,11 +88,10 @@ where
             .into_iter()
             .map(|name| {
                 let source = self.source.get(name).and_then(|s| {
-                    liquid_compiler::parse(s.as_ref(), &language)
-                        .map(liquid_interpreter::Template::new)
+                    compiler::parse(s.as_ref(), &language)
+                        .map(interpreter::Template::new)
                         .map(|t| {
-                            let t: sync::Arc<dyn liquid_interpreter::Renderable> =
-                                sync::Arc::new(t);
+                            let t: sync::Arc<dyn interpreter::Renderable> = sync::Arc::new(t);
                             t
                         })
                 });
@@ -109,7 +108,7 @@ where
 }
 
 struct EagerStore {
-    store: HashMap<String, Result<sync::Arc<dyn liquid_interpreter::Renderable>>>,
+    store: HashMap<String, Result<sync::Arc<dyn interpreter::Renderable>>>,
 }
 
 impl PartialStore for EagerStore {
@@ -139,7 +138,7 @@ impl PartialStore for EagerStore {
 }
 
 impl fmt::Debug for EagerStore {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.names().fmt(f)
     }
 }
diff --git a/src/partials/lazy.rs b/src/partials/lazy.rs
index f728ef8..945de24 100644
--- a/src/partials/lazy.rs
+++ b/src/partials/lazy.rs
@@ -2,12 +2,12 @@ use std::collections::HashMap;
 use std::fmt;
 use std::sync;
 
-use liquid_compiler;
-use liquid_compiler::Language;
-use liquid_error::Result;
-use liquid_interpreter;
-use liquid_interpreter::PartialStore;
-use liquid_interpreter::Renderable;
+use liquid_core::compiler;
+use liquid_core::compiler::Language;
+use liquid_core::error::Result;
+use liquid_core::interpreter;
+use liquid_core::interpreter::PartialStore;
+use liquid_core::interpreter::Renderable;
 
 use super::PartialCompiler;
 use super::PartialSource;
@@ -97,7 +97,7 @@ where
 struct LazyStore<S: PartialSource> {
     language: sync::Arc<Language>,
     source: S,
-    cache: sync::Mutex<HashMap<String, Result<sync::Arc<dyn liquid_interpreter::Renderable>>>>,
+    cache: sync::Mutex<HashMap<String, Result<sync::Arc<dyn interpreter::Renderable>>>>,
 }
 
 impl<S> LazyStore<S>
@@ -111,8 +111,8 @@ where
         } else {
             let s = self.source.try_get(name)?;
             let s = s.as_ref();
-            let template = liquid_compiler::parse(s, &self.language)
-                .map(liquid_interpreter::Template::new)
+            let template = compiler::parse(s, &self.language)
+                .map(interpreter::Template::new)
                 .map(sync::Arc::new)
                 .ok()?;
             Some(template)
@@ -126,8 +126,8 @@ where
         } else {
             let s = self.source.get(name)?;
             let s = s.as_ref();
-            let template = liquid_compiler::parse(s, &self.language)
-                .map(liquid_interpreter::Template::new)
+            let template = compiler::parse(s, &self.language)
+                .map(interpreter::Template::new)
                 .map(sync::Arc::new)?;
             Ok(template)
         }
@@ -159,7 +159,7 @@ impl<S> fmt::Debug for LazyStore<S>
 where
     S: PartialSource,
 {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.source.fmt(f)
     }
 }
diff --git a/src/partials/mod.rs b/src/partials/mod.rs
index 9f4e039..b6c6967 100644
--- a/src/partials/mod.rs
+++ b/src/partials/mod.rs
@@ -2,10 +2,10 @@ use std::borrow;
 use std::fmt;
 use std::sync;
 
-use liquid_compiler::Language;
-use liquid_error::Error;
-use liquid_error::Result;
-use liquid_interpreter::PartialStore;
+use liquid_core::compiler::Language;
+use liquid_core::error::Error;
+use liquid_core::error::Result;
+use liquid_core::interpreter::PartialStore;
 
 mod eager;
 mod inmemory;
diff --git a/src/partials/ondemand.rs b/src/partials/ondemand.rs
index 96f633d..ecf30cb 100644
--- a/src/partials/ondemand.rs
+++ b/src/partials/ondemand.rs
@@ -1,12 +1,12 @@
 use std::fmt;
 use std::sync;
 
-use liquid_compiler;
-use liquid_compiler::Language;
-use liquid_error::Result;
-use liquid_interpreter;
-use liquid_interpreter::PartialStore;
-use liquid_interpreter::Renderable;
+use liquid_core::compiler;
+use liquid_core::compiler::Language;
+use liquid_core::error::Result;
+use liquid_core::interpreter;
+use liquid_core::interpreter::PartialStore;
+use liquid_core::interpreter::Renderable;
 
 use super::PartialCompiler;
 use super::PartialSource;
@@ -111,8 +111,8 @@ where
     fn try_get(&self, name: &str) -> Option<sync::Arc<dyn Renderable>> {
         let s = self.source.try_get(name)?;
         let s = s.as_ref();
-        let template = liquid_compiler::parse(s, &self.language)
-            .map(liquid_interpreter::Template::new)
+        let template = compiler::parse(s, &self.language)
+            .map(interpreter::Template::new)
             .map(sync::Arc::new)
             .ok()?;
         Some(template)
@@ -121,8 +121,8 @@ where
     fn get(&self, name: &str) -> Result<sync::Arc<dyn Renderable>> {
         let s = self.source.get(name)?;
         let s = s.as_ref();
-        let template = liquid_compiler::parse(s, &self.language)
-            .map(liquid_interpreter::Template::new)
+        let template = compiler::parse(s, &self.language)
+            .map(interpreter::Template::new)
             .map(sync::Arc::new)?;
         Ok(template)
     }
@@ -132,7 +132,7 @@ impl<S> fmt::Debug for OnDemandStore<S>
 where
     S: PartialSource,
 {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         self.source.fmt(f)
     }
 }
diff --git a/src/reflection.rs b/src/reflection.rs
index df95ca9..5ae8e0b 100644
--- a/src/reflection.rs
+++ b/src/reflection.rs
@@ -1,4 +1,4 @@
-use liquid_compiler as compiler;
+use liquid_core::compiler;
 
 pub trait ParserReflection {
     fn blocks<'r>(&'r self) -> Box<dyn Iterator<Item = &dyn compiler::BlockReflection> + 'r>;
diff --git a/src/tags/assign_tag.rs b/src/tags/assign_tag.rs
index 84791bb..86880b7 100644
--- a/src/tags/assign_tag.rs
+++ b/src/tags/assign_tag.rs
@@ -1,15 +1,12 @@
 use std::io::Write;
 
-use liquid_error::Result;
-use liquid_error::ResultLiquidExt;
-
-use compiler::FilterChain;
-use compiler::Language;
-use compiler::ParseTag;
-use compiler::TagReflection;
-use compiler::TagTokenIter;
-use interpreter::Context;
-use interpreter::Renderable;
+use liquid_core::compiler::FilterChain;
+use liquid_core::error::ResultLiquidExt;
+use liquid_core::Context;
+use liquid_core::Language;
+use liquid_core::Renderable;
+use liquid_core::Result;
+use liquid_core::{ParseTag, TagReflection, TagTokenIter};
 
 #[derive(Debug)]
 struct Assign {
@@ -24,7 +21,7 @@ impl Assign {
 }
 
 impl Renderable for Assign {
-    fn render_to(&self, _writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, _writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         let value = self
             .src
             .evaluate(context)
@@ -56,7 +53,7 @@ impl TagReflection for AssignTag {
 impl ParseTag for AssignTag {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
+        mut arguments: TagTokenIter<'_>,
         options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         let dst = arguments
@@ -89,12 +86,14 @@ impl ParseTag for AssignTag {
 #[cfg(test)]
 mod test {
     use super::*;
-    use compiler;
-    use interpreter;
-    use tags;
-    use value::Scalar;
-    use value::Value;
-    use value::ValueViewCmp;
+
+    use liquid_core::compiler;
+    use liquid_core::interpreter;
+    use liquid_core::value::Scalar;
+    use liquid_core::value::Value;
+    use liquid_core::value::ValueViewCmp;
+
+    use crate::tags;
 
     fn options() -> Language {
         let mut options = Language::default();
diff --git a/src/tags/capture_block.rs b/src/tags/capture_block.rs
index 62faa1c..33dc757 100644
--- a/src/tags/capture_block.rs
+++ b/src/tags/capture_block.rs
@@ -1,16 +1,13 @@
 use std::io::Write;
 
-use liquid_error::{Result, ResultLiquidExt};
-use liquid_value::Value;
-
-use compiler::BlockReflection;
-use compiler::Language;
-use compiler::ParseBlock;
-use compiler::TagBlock;
-use compiler::TagTokenIter;
-use interpreter::Context;
-use interpreter::Renderable;
-use interpreter::Template;
+use liquid_core::error::ResultLiquidExt;
+use liquid_core::value::Value;
+use liquid_core::Context;
+use liquid_core::Language;
+use liquid_core::Renderable;
+use liquid_core::Result;
+use liquid_core::Template;
+use liquid_core::{BlockReflection, ParseBlock, TagBlock, TagTokenIter};
 
 #[derive(Debug)]
 struct Capture {
@@ -25,7 +22,7 @@ impl Capture {
 }
 
 impl Renderable for Capture {
-    fn render_to(&self, _writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, _writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         let mut captured = Vec::new();
         self.template
             .render_to(&mut captured, context)
@@ -65,8 +62,8 @@ impl BlockReflection for CaptureBlock {
 impl ParseBlock for CaptureBlock {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
-        mut tokens: TagBlock,
+        mut arguments: TagTokenIter<'_>,
+        mut tokens: TagBlock<'_, '_>,
         options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         let id = arguments
@@ -96,10 +93,11 @@ impl ParseBlock for CaptureBlock {
 #[cfg(test)]
 mod test {
     use super::*;
-    use compiler;
-    use interpreter;
-    use value::Scalar;
-    use value::ValueViewCmp;
+
+    use liquid_core::compiler;
+    use liquid_core::interpreter;
+    use liquid_core::value::Scalar;
+    use liquid_core::value::ValueViewCmp;
 
     fn options() -> Language {
         let mut options = Language::default();
diff --git a/src/tags/case_block.rs b/src/tags/case_block.rs
index c44504b..cab35e9 100644
--- a/src/tags/case_block.rs
+++ b/src/tags/case_block.rs
@@ -1,20 +1,17 @@
 use std::io::Write;
 
 use itertools;
-use liquid_error::{Result, ResultLiquidExt};
-use liquid_value::{ValueView, ValueViewCmp};
-
-use compiler::BlockElement;
-use compiler::BlockReflection;
-use compiler::Language;
-use compiler::ParseBlock;
-use compiler::TagBlock;
-use compiler::TagTokenIter;
-use compiler::TryMatchToken;
-use interpreter::Context;
-use interpreter::Expression;
-use interpreter::Renderable;
-use interpreter::Template;
+use liquid_core::compiler::BlockElement;
+use liquid_core::compiler::TryMatchToken;
+use liquid_core::error::ResultLiquidExt;
+use liquid_core::value::{ValueView, ValueViewCmp};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Language;
+use liquid_core::Renderable;
+use liquid_core::Result;
+use liquid_core::Template;
+use liquid_core::{BlockReflection, ParseBlock, TagBlock, TagTokenIter};
 
 #[derive(Debug)]
 struct CaseOption {
@@ -27,7 +24,7 @@ impl CaseOption {
         CaseOption { args, template }
     }
 
-    fn evaluate(&self, value: &dyn ValueView, context: &Context) -> Result<bool> {
+    fn evaluate(&self, value: &dyn ValueView, context: &Context<'_>) -> Result<bool> {
         for a in &self.args {
             let v = a.evaluate(context)?;
             if ValueViewCmp::new(v) == ValueViewCmp::new(value) {
@@ -56,7 +53,7 @@ impl Case {
 }
 
 impl Renderable for Case {
-    fn render_to(&self, writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         let value = self.target.evaluate(context)?.to_value();
         for case in &self.cases {
             if case.evaluate(&value, context)? {
@@ -83,7 +80,7 @@ impl Renderable for Case {
     }
 }
 
-fn parse_condition(arguments: &mut TagTokenIter) -> Result<Vec<Expression>> {
+fn parse_condition(arguments: &mut TagTokenIter<'_>) -> Result<Vec<Expression>> {
     let mut values = Vec::new();
 
     let first_value = arguments
@@ -137,8 +134,8 @@ impl BlockReflection for CaseBlock {
 impl ParseBlock for CaseBlock {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
-        mut tokens: TagBlock,
+        mut arguments: TagTokenIter<'_>,
+        mut tokens: TagBlock<'_, '_>,
         options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         let target = arguments
@@ -198,9 +195,10 @@ impl ParseBlock for CaseBlock {
 #[cfg(test)]
 mod test {
     use super::*;
-    use compiler;
-    use interpreter;
-    use liquid_value::Value;
+
+    use liquid_core::compiler;
+    use liquid_core::interpreter;
+    use liquid_core::value::Value;
 
     fn options() -> Language {
         let mut options = Language::default();
diff --git a/src/tags/comment_block.rs b/src/tags/comment_block.rs
index 63142be..fe3b3ea 100644
--- a/src/tags/comment_block.rs
+++ b/src/tags/comment_block.rs
@@ -1,21 +1,17 @@
 use std::io::Write;
 
-use liquid_error::Result;
-
-use compiler::BlockElement;
-use compiler::BlockReflection;
-use compiler::Language;
-use compiler::ParseBlock;
-use compiler::TagBlock;
-use compiler::TagTokenIter;
-use interpreter::Context;
-use interpreter::Renderable;
+use liquid_core::compiler::BlockElement;
+use liquid_core::Context;
+use liquid_core::Language;
+use liquid_core::Renderable;
+use liquid_core::Result;
+use liquid_core::{BlockReflection, ParseBlock, TagBlock, TagTokenIter};
 
 #[derive(Copy, Clone, Debug)]
 struct Comment;
 
 impl Renderable for Comment {
-    fn render_to(&self, _writer: &mut dyn Write, _context: &mut Context) -> Result<()> {
+    fn render_to(&self, _writer: &mut dyn Write, _context: &mut Context<'_>) -> Result<()> {
         Ok(())
     }
 }
@@ -46,8 +42,8 @@ impl BlockReflection for CommentBlock {
 impl ParseBlock for CommentBlock {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
-        mut tokens: TagBlock,
+        mut arguments: TagTokenIter<'_>,
+        mut tokens: TagBlock<'_, '_>,
         options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         // no arguments should be supplied, trying to supply them is an error
@@ -79,8 +75,9 @@ impl ParseBlock for CommentBlock {
 #[cfg(test)]
 mod test {
     use super::*;
-    use compiler;
-    use interpreter;
+
+    use liquid_core::compiler;
+    use liquid_core::interpreter;
 
     fn options() -> Language {
         let mut options = Language::default();
diff --git a/src/tags/cycle_tag.rs b/src/tags/cycle_tag.rs
index dbbef97..3f94148 100644
--- a/src/tags/cycle_tag.rs
+++ b/src/tags/cycle_tag.rs
@@ -2,18 +2,16 @@ use std::collections::HashMap;
 use std::io::Write;
 
 use itertools;
-use liquid_error::{Error, Result, ResultLiquidExt, ResultLiquidReplaceExt};
-
-use compiler::Language;
-use compiler::ParseTag;
-use compiler::TagReflection;
-use compiler::TagToken;
-use compiler::TagTokenIter;
-use compiler::TryMatchToken;
-use interpreter::Context;
-use interpreter::Expression;
-use interpreter::Renderable;
-use value::ValueView;
+use liquid_core::compiler::TagToken;
+use liquid_core::compiler::TryMatchToken;
+use liquid_core::error::{ResultLiquidExt, ResultLiquidReplaceExt};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Language;
+use liquid_core::Renderable;
+use liquid_core::ValueView;
+use liquid_core::{Error, Result};
+use liquid_core::{ParseTag, TagReflection, TagTokenIter};
 
 #[derive(Clone, Debug)]
 struct Cycle {
@@ -31,7 +29,7 @@ impl Cycle {
 }
 
 impl Renderable for Cycle {
-    fn render_to(&self, writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         let expr = context
             .get_register_mut::<State>()
             .cycle(&self.name, &self.values)
@@ -43,7 +41,7 @@ impl Renderable for Cycle {
 }
 
 /// Internal implementation of cycle, to allow easier testing.
-fn parse_cycle(mut arguments: TagTokenIter, _options: &Language) -> Result<Cycle> {
+fn parse_cycle(mut arguments: TagTokenIter<'_>, _options: &Language) -> Result<Cycle> {
     let mut name = String::new();
     let mut values = Vec::new();
 
@@ -123,7 +121,11 @@ impl TagReflection for CycleTag {
 }
 
 impl ParseTag for CycleTag {
-    fn parse(&self, arguments: TagTokenIter, options: &Language) -> Result<Box<dyn Renderable>> {
+    fn parse(
+        &self,
+        arguments: TagTokenIter<'_>,
+        options: &Language,
+    ) -> Result<Box<dyn Renderable>> {
         parse_cycle(arguments, options).map(|opt| Box::new(opt) as Box<dyn Renderable>)
     }
 
@@ -164,9 +166,10 @@ impl State {
 #[cfg(test)]
 mod test {
     use super::*;
-    use compiler;
-    use interpreter;
-    use value::Value;
+
+    use liquid_core::compiler;
+    use liquid_core::interpreter;
+    use liquid_core::value::Value;
 
     fn options() -> Language {
         let mut options = Language::default();
diff --git a/src/tags/for_block.rs b/src/tags/for_block.rs
index a111692..f76a1aa 100644
--- a/src/tags/for_block.rs
+++ b/src/tags/for_block.rs
@@ -2,20 +2,18 @@ use std::fmt;
 use std::io::Write;
 
 use itertools;
-use liquid_error::{Error, Result, ResultLiquidExt, ResultLiquidReplaceExt};
-use liquid_value::{Object, Value};
-
-use compiler::BlockElement;
-use compiler::BlockReflection;
-use compiler::Language;
-use compiler::ParseBlock;
-use compiler::TagBlock;
-use compiler::TagTokenIter;
-use compiler::TryMatchToken;
-use interpreter::Expression;
-use interpreter::Renderable;
-use interpreter::Template;
-use interpreter::{Context, Interrupt};
+use liquid_core::compiler::BlockElement;
+use liquid_core::compiler::TryMatchToken;
+use liquid_core::error::{ResultLiquidExt, ResultLiquidReplaceExt};
+use liquid_core::interpreter::Interrupt;
+use liquid_core::value::{Object, Value};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Language;
+use liquid_core::Renderable;
+use liquid_core::Template;
+use liquid_core::{BlockReflection, ParseBlock, TagBlock, TagTokenIter};
+use liquid_core::{Error, Result};
 
 #[derive(Clone, Debug)]
 enum Range {
@@ -24,7 +22,7 @@ enum Range {
 }
 
 impl Range {
-    pub fn evaluate(&self, context: &Context) -> Result<Vec<Value>> {
+    pub fn evaluate(&self, context: &Context<'_>) -> Result<Vec<Value>> {
         let range = match *self {
             Range::Array(ref array_id) => get_array(context, array_id)?,
 
@@ -41,7 +39,7 @@ impl Range {
 }
 
 impl fmt::Display for Range {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             Range::Array(ref arr) => write!(f, "{}", arr),
             Range::Counted(ref start, ref end) => write!(f, "({}..{})", start, end),
@@ -70,7 +68,7 @@ fn iter_array(
 }
 
 /// Extracts an integer value or an identifier from the token stream
-fn parse_attr(arguments: &mut TagTokenIter) -> Result<Expression> {
+fn parse_attr(arguments: &mut TagTokenIter<'_>) -> Result<Expression> {
     arguments
         .expect_next("\":\" expected.")?
         .expect_str(":")
@@ -83,7 +81,7 @@ fn parse_attr(arguments: &mut TagTokenIter) -> Result<Expression> {
 }
 
 /// Evaluates an attribute, returning Ok(None) if input is also None.
-fn evaluate_attr(attr: &Option<Expression>, context: &mut Context) -> Result<Option<usize>> {
+fn evaluate_attr(attr: &Option<Expression>, context: &mut Context<'_>) -> Result<Option<usize>> {
     match attr {
         Some(attr) => {
             let value = attr.evaluate(context)?;
@@ -121,7 +119,7 @@ impl For {
     }
 }
 
-fn get_array(context: &Context, array_id: &Expression) -> Result<Vec<Value>> {
+fn get_array(context: &Context<'_>, array_id: &Expression) -> Result<Vec<Value>> {
     let array = array_id.evaluate(context)?;
     if let Some(x) = array.as_array() {
         Ok(x.values().map(|v| v.to_value()).collect())
@@ -142,7 +140,7 @@ fn get_array(context: &Context, array_id: &Expression) -> Result<Vec<Value>> {
     }
 }
 
-fn int_argument(arg: &Expression, context: &Context, arg_name: &str) -> Result<isize> {
+fn int_argument(arg: &Expression, context: &Context<'_>, arg_name: &str) -> Result<isize> {
     let value = arg.evaluate(context)?;
 
     let value = value
@@ -156,7 +154,7 @@ fn int_argument(arg: &Expression, context: &Context, arg_name: &str) -> Result<i
 }
 
 impl Renderable for For {
-    fn render_to(&self, writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         let range = self
             .range
             .evaluate(context)
@@ -265,8 +263,8 @@ impl BlockReflection for ForBlock {
 impl ParseBlock for ForBlock {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
-        mut tokens: TagBlock,
+        mut arguments: TagTokenIter<'_>,
+        mut tokens: TagBlock<'_, '_>,
         options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         let var_name = arguments
@@ -396,7 +394,7 @@ fn trace_tablerow_tag(
 }
 
 impl Renderable for TableRow {
-    fn render_to(&self, writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         let range = self
             .range
             .evaluate(context)
@@ -489,8 +487,8 @@ impl BlockReflection for TableRowBlock {
 impl ParseBlock for TableRowBlock {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
-        mut tokens: TagBlock,
+        mut arguments: TagTokenIter<'_>,
+        mut tokens: TagBlock<'_, '_>,
         options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         let var_name = arguments
@@ -565,13 +563,13 @@ fn unexpected_value_error_string(expected: &str, actual: Option<String>) -> Erro
 
 #[cfg(test)]
 mod test {
-    use compiler;
-    use compiler::Filter;
-    use derive::*;
-    use interpreter;
-    use interpreter::ContextBuilder;
-    use liquid::value::ValueView;
-    use tags;
+    use liquid_core::compiler;
+    use liquid_core::interpreter;
+    use liquid_core::interpreter::ContextBuilder;
+    use liquid_core::value::ValueView;
+    use liquid_core::{Display_filter, Filter, FilterReflection, ParseFilter};
+
+    use crate::tags;
 
     use super::*;
 
@@ -595,7 +593,7 @@ mod test {
             .map(interpreter::Template::new)
             .unwrap();
 
-        let mut context: Context = Default::default();
+        let mut context: Context<'_> = Default::default();
         context.stack_mut().set_global(
             "array",
             Value::Array(vec![
@@ -857,7 +855,7 @@ mod test {
             .map(interpreter::Template::new)
             .unwrap();
 
-        let mut context: Context = Default::default();
+        let mut context: Context<'_> = Default::default();
         let output = template.render(&mut context).unwrap();
         assert_eq!(
                 output,
@@ -878,7 +876,7 @@ mod test {
     pub struct ShoutFilter;
 
     impl Filter for ShoutFilter {
-        fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+        fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
             Ok(Value::scalar(input.to_kstr().to_uppercase()))
         }
     }
@@ -943,7 +941,7 @@ mod test {
             .map(interpreter::Template::new)
             .unwrap();
 
-        let mut context: Context = Default::default();
+        let mut context: Context<'_> = Default::default();
         context.stack_mut().set_global(
             "array",
             Value::Array(vec![
@@ -969,7 +967,7 @@ mod test {
             .map(interpreter::Template::new)
             .unwrap();
 
-        let mut context: Context = Default::default();
+        let mut context: Context<'_> = Default::default();
         context.stack_mut().set_global(
             "array",
             Value::Array(vec![
@@ -1028,7 +1026,7 @@ mod test {
             .map(interpreter::Template::new)
             .unwrap();
 
-        let mut context: Context = Default::default();
+        let mut context: Context<'_> = Default::default();
         let output = template.render(&mut context).unwrap();
         assert_eq!(
                 output,
diff --git a/src/tags/if_block.rs b/src/tags/if_block.rs
index d502a2e..11e69fb 100644
--- a/src/tags/if_block.rs
+++ b/src/tags/if_block.rs
@@ -1,20 +1,17 @@
 use std::fmt;
 use std::io::Write;
 
-use liquid_error::{Error, Result, ResultLiquidExt};
-use liquid_value::{Value, ValueView, ValueViewCmp};
-
-use compiler::BlockElement;
-use compiler::BlockReflection;
-use compiler::Language;
-use compiler::ParseBlock;
-use compiler::TagBlock;
-use compiler::TagToken;
-use compiler::TagTokenIter;
-use interpreter::Context;
-use interpreter::Expression;
-use interpreter::Renderable;
-use interpreter::Template;
+use liquid_core::compiler::BlockElement;
+use liquid_core::compiler::TagToken;
+use liquid_core::error::ResultLiquidExt;
+use liquid_core::value::{Value, ValueView, ValueViewCmp};
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Language;
+use liquid_core::Renderable;
+use liquid_core::Template;
+use liquid_core::{BlockReflection, ParseBlock, TagBlock, TagTokenIter};
+use liquid_core::{Error, Result};
 
 #[derive(Clone, Debug)]
 enum ComparisonOperator {
@@ -28,7 +25,7 @@ enum ComparisonOperator {
 }
 
 impl fmt::Display for ComparisonOperator {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let out = match *self {
             ComparisonOperator::Equals => "==",
             ComparisonOperator::NotEquals => "!=",
@@ -65,7 +62,7 @@ struct BinaryCondition {
 }
 
 impl BinaryCondition {
-    pub fn evaluate(&self, context: &Context) -> Result<bool> {
+    pub fn evaluate(&self, context: &Context<'_>) -> Result<bool> {
         let a = self.lh.evaluate(context)?;
         let ca = ValueViewCmp::new(a);
         let b = self.rh.evaluate(context)?;
@@ -86,7 +83,7 @@ impl BinaryCondition {
 }
 
 impl fmt::Display for BinaryCondition {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "{} {} {}", self.lh, self.comparison, self.rh)
     }
 }
@@ -99,14 +96,14 @@ struct ExistenceCondition {
 static NIL: Value = Value::Nil;
 
 impl ExistenceCondition {
-    pub fn evaluate(&self, context: &Context) -> Result<bool> {
+    pub fn evaluate(&self, context: &Context<'_>) -> Result<bool> {
         let a = self.lh.try_evaluate(context).unwrap_or(&NIL);
-        Ok(a.query_state(liquid_value::State::Truthy))
+        Ok(a.query_state(liquid_core::value::State::Truthy))
     }
 }
 
 impl fmt::Display for ExistenceCondition {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         write!(f, "{}", self.lh)
     }
 }
@@ -120,7 +117,7 @@ enum Condition {
 }
 
 impl Condition {
-    pub fn evaluate(&self, context: &Context) -> Result<bool> {
+    pub fn evaluate(&self, context: &Context<'_>) -> Result<bool> {
         match *self {
             Condition::Binary(ref c) => c.evaluate(context),
             Condition::Existence(ref c) => c.evaluate(context),
@@ -135,7 +132,7 @@ impl Condition {
 }
 
 impl fmt::Display for Condition {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             Condition::Binary(ref c) => write!(f, "{}", c),
             Condition::Existence(ref c) => write!(f, "{}", c),
@@ -180,7 +177,7 @@ fn contains_check(a: &dyn ValueView, b: &dyn ValueView) -> Result<bool> {
 }
 
 impl Conditional {
-    fn compare(&self, context: &Context) -> Result<bool> {
+    fn compare(&self, context: &Context<'_>) -> Result<bool> {
         let result = self.condition.evaluate(context)?;
 
         Ok(result == self.mode)
@@ -192,7 +189,7 @@ impl Conditional {
 }
 
 impl Renderable for Conditional {
-    fn render_to(&self, writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         let condition = self.compare(context).trace_with(|| self.trace().into())?;
         if condition {
             self.if_true
@@ -242,7 +239,7 @@ impl<'a> PeekableTagTokenIter<'a> {
     }
 }
 
-fn parse_atom_condition(arguments: &mut PeekableTagTokenIter) -> Result<Condition> {
+fn parse_atom_condition(arguments: &mut PeekableTagTokenIter<'_>) -> Result<Condition> {
     let lh = arguments
         .expect_next("Value expected.")?
         .expect_value()
@@ -270,7 +267,7 @@ fn parse_atom_condition(arguments: &mut PeekableTagTokenIter) -> Result<Conditio
     Ok(cond)
 }
 
-fn parse_conjunction_chain(arguments: &mut PeekableTagTokenIter) -> Result<Condition> {
+fn parse_conjunction_chain(arguments: &mut PeekableTagTokenIter<'_>) -> Result<Condition> {
     let mut lh = parse_atom_condition(arguments)?;
 
     while let Some("and") = arguments.peek().map(TagToken::as_str) {
@@ -283,7 +280,7 @@ fn parse_conjunction_chain(arguments: &mut PeekableTagTokenIter) -> Result<Condi
 }
 
 /// Common parsing for "if" and "unless" condition
-fn parse_condition(arguments: TagTokenIter) -> Result<Condition> {
+fn parse_condition(arguments: TagTokenIter<'_>) -> Result<Condition> {
     let mut arguments = PeekableTagTokenIter {
         iter: arguments,
         peeked: None,
@@ -328,8 +325,8 @@ impl BlockReflection for UnlessBlock {
 impl ParseBlock for UnlessBlock {
     fn parse(
         &self,
-        arguments: TagTokenIter,
-        mut tokens: TagBlock,
+        arguments: TagTokenIter<'_>,
+        mut tokens: TagBlock<'_, '_>,
         options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         let condition = parse_condition(arguments)?;
@@ -370,8 +367,8 @@ impl ParseBlock for UnlessBlock {
 
 fn parse_if(
     tag_name: &str,
-    arguments: TagTokenIter,
-    tokens: &mut TagBlock,
+    arguments: TagTokenIter<'_>,
+    tokens: &mut TagBlock<'_, '_>,
     options: &Language,
 ) -> Result<Box<dyn Renderable>> {
     let condition = parse_condition(arguments)?;
@@ -434,8 +431,8 @@ impl BlockReflection for IfBlock {
 impl ParseBlock for IfBlock {
     fn parse(
         &self,
-        arguments: TagTokenIter,
-        mut tokens: TagBlock,
+        arguments: TagTokenIter<'_>,
+        mut tokens: TagBlock<'_, '_>,
         options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         let conditional = parse_if(self.start_tag(), arguments, &mut tokens, options)?;
@@ -463,10 +460,11 @@ fn unexpected_value_error_string(expected: &str, actual: Option<String>) -> Erro
 #[cfg(test)]
 mod test {
     use super::*;
-    use compiler;
-    use interpreter;
-    use value::Object;
-    use value::Value;
+
+    use liquid_core::compiler;
+    use liquid_core::interpreter;
+    use liquid_core::value::Object;
+    use liquid_core::value::Value;
 
     fn options() -> Language {
         let mut options = Language::default();
diff --git a/src/tags/ifchanged_block.rs b/src/tags/ifchanged_block.rs
index 05932d4..363b69e 100644
--- a/src/tags/ifchanged_block.rs
+++ b/src/tags/ifchanged_block.rs
@@ -1,15 +1,12 @@
 use std::io::Write;
 
-use liquid_error::{Result, ResultLiquidExt, ResultLiquidReplaceExt};
-
-use compiler::BlockReflection;
-use compiler::Language;
-use compiler::ParseBlock;
-use compiler::TagBlock;
-use compiler::TagTokenIter;
-use interpreter::Context;
-use interpreter::Renderable;
-use interpreter::Template;
+use liquid_core::error::{ResultLiquidExt, ResultLiquidReplaceExt};
+use liquid_core::Context;
+use liquid_core::Language;
+use liquid_core::Renderable;
+use liquid_core::Result;
+use liquid_core::Template;
+use liquid_core::{BlockReflection, ParseBlock, TagBlock, TagTokenIter};
 
 #[derive(Debug)]
 struct IfChanged {
@@ -23,7 +20,7 @@ impl IfChanged {
 }
 
 impl Renderable for IfChanged {
-    fn render_to(&self, writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         let mut rendered = Vec::new();
         self.if_changed
             .render_to(&mut rendered, context)
@@ -64,8 +61,8 @@ impl BlockReflection for IfChangedBlock {
 impl ParseBlock for IfChangedBlock {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
-        mut tokens: TagBlock,
+        mut arguments: TagTokenIter<'_>,
+        mut tokens: TagBlock<'_, '_>,
         options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         // no arguments should be supplied, trying to supply them is an error
@@ -106,9 +103,11 @@ impl State {
 #[cfg(test)]
 mod test {
     use super::*;
-    use compiler;
-    use interpreter;
-    use tags;
+
+    use liquid_core::compiler;
+    use liquid_core::interpreter;
+
+    use crate::tags;
 
     fn options() -> Language {
         let mut options = Language::default();
diff --git a/src/tags/include_tag.rs b/src/tags/include_tag.rs
index 03614cb..8c065c3 100644
--- a/src/tags/include_tag.rs
+++ b/src/tags/include_tag.rs
@@ -1,16 +1,14 @@
 use std::io::Write;
 
-use liquid_error::{Result, ResultLiquidExt};
-
-use compiler::Language;
-use compiler::ParseTag;
-use compiler::TagReflection;
-use compiler::TagTokenIter;
-use compiler::TryMatchToken;
-use interpreter::Context;
-use interpreter::Expression;
-use interpreter::Renderable;
-use value::ValueView;
+use liquid_core::compiler::TryMatchToken;
+use liquid_core::error::ResultLiquidExt;
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Language;
+use liquid_core::Renderable;
+use liquid_core::Result;
+use liquid_core::ValueView;
+use liquid_core::{ParseTag, TagReflection, TagTokenIter};
 
 #[derive(Debug)]
 struct Include {
@@ -18,7 +16,7 @@ struct Include {
 }
 
 impl Renderable for Include {
-    fn render_to(&self, writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         let name = self.partial.evaluate(context)?.render().to_string();
         context.run_in_named_scope(name.clone(), |mut scope| -> Result<()> {
             let partial = scope
@@ -58,7 +56,7 @@ impl TagReflection for IncludeTag {
 impl ParseTag for IncludeTag {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
+        mut arguments: TagTokenIter<'_>,
         _options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         let name = arguments.expect_next("Identifier or literal expected.")?;
@@ -88,16 +86,15 @@ impl ParseTag for IncludeTag {
 mod test {
     use std::borrow;
 
-    use compiler;
-    use compiler::Filter;
-    use derive::*;
-    use interpreter;
-    use interpreter::ContextBuilder;
-    use partials;
-    use partials::PartialCompiler;
-    use tags;
-    use value;
-    use value::Value;
+    use liquid_core::compiler;
+    use liquid_core::interpreter;
+    use liquid_core::interpreter::ContextBuilder;
+    use liquid_core::Value;
+    use liquid_core::{Display_filter, Filter, FilterReflection, ParseFilter};
+
+    use crate::partials;
+    use crate::partials::PartialCompiler;
+    use crate::tags;
 
     use super::*;
 
@@ -144,7 +141,7 @@ mod test {
     pub struct SizeFilter;
 
     impl Filter for SizeFilter {
-        fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+        fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
             match *input {
                 Value::Scalar(ref x) => Ok(Value::scalar(x.to_kstr().len() as i32)),
                 Value::Array(ref x) => Ok(Value::scalar(x.len() as i32)),
@@ -171,12 +168,10 @@ mod test {
         let mut context = ContextBuilder::new()
             .set_partials(partials.as_ref())
             .build();
+        context.stack_mut().set_global("num", Value::scalar(5f64));
         context
             .stack_mut()
-            .set_global("num", value::Value::scalar(5f64));
-        context
-            .stack_mut()
-            .set_global("numTwo", value::Value::scalar(10f64));
+            .set_global("numTwo", Value::scalar(10f64));
         let output = template.render(&mut context).unwrap();
         assert_eq!(output, "5 wat wot");
     }
@@ -198,12 +193,10 @@ mod test {
         let mut context = ContextBuilder::new()
             .set_partials(partials.as_ref())
             .build();
+        context.stack_mut().set_global("num", Value::scalar(5f64));
         context
             .stack_mut()
-            .set_global("num", value::Value::scalar(5f64));
-        context
-            .stack_mut()
-            .set_global("numTwo", value::Value::scalar(10f64));
+            .set_global("numTwo", Value::scalar(10f64));
         let output = template.render(&mut context).unwrap();
         assert_eq!(output, "5 wat wot");
     }
@@ -225,12 +218,10 @@ mod test {
         let mut context = ContextBuilder::new()
             .set_partials(partials.as_ref())
             .build();
+        context.stack_mut().set_global("num", Value::scalar(5f64));
         context
             .stack_mut()
-            .set_global("num", value::Value::scalar(5f64));
-        context
-            .stack_mut()
-            .set_global("numTwo", value::Value::scalar(10f64));
+            .set_global("numTwo", Value::scalar(10f64));
         let output = template.render(&mut context);
         assert!(output.is_err());
     }
diff --git a/src/tags/increment_tags.rs b/src/tags/increment_tags.rs
index 5168032..c033ed7 100644
--- a/src/tags/increment_tags.rs
+++ b/src/tags/increment_tags.rs
@@ -1,14 +1,12 @@
 use std::io::Write;
 
-use liquid_error::{Result, ResultLiquidReplaceExt};
-
-use compiler::Language;
-use compiler::ParseTag;
-use compiler::TagReflection;
-use compiler::TagTokenIter;
-use interpreter::Context;
-use interpreter::Renderable;
-use value::{Value, ValueView};
+use liquid_core::error::ResultLiquidReplaceExt;
+use liquid_core::value::{Value, ValueView};
+use liquid_core::Context;
+use liquid_core::Language;
+use liquid_core::Renderable;
+use liquid_core::Result;
+use liquid_core::{ParseTag, TagReflection, TagTokenIter};
 
 #[derive(Clone, Debug)]
 struct Increment {
@@ -16,7 +14,7 @@ struct Increment {
 }
 
 impl Renderable for Increment {
-    fn render_to(&self, writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         let mut val = context
             .stack()
             .get_index(&self.id)
@@ -55,7 +53,7 @@ impl TagReflection for IncrementTag {
 impl ParseTag for IncrementTag {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
+        mut arguments: TagTokenIter<'_>,
         _options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         let id = arguments
@@ -81,7 +79,7 @@ struct Decrement {
 }
 
 impl Renderable for Decrement {
-    fn render_to(&self, writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         let mut val = context
             .stack()
             .get_index(&self.id)
@@ -120,7 +118,7 @@ impl TagReflection for DecrementTag {
 impl ParseTag for DecrementTag {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
+        mut arguments: TagTokenIter<'_>,
         _options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         let id = arguments
@@ -143,9 +141,11 @@ impl ParseTag for DecrementTag {
 #[cfg(test)]
 mod test {
     use super::*;
-    use compiler;
-    use interpreter;
-    use tags;
+
+    use liquid_core::compiler;
+    use liquid_core::interpreter;
+
+    use crate::tags;
 
     fn options() -> Language {
         let mut options = Language::default();
diff --git a/src/tags/interrupt_tags.rs b/src/tags/interrupt_tags.rs
index ebb4efc..278f9e7 100644
--- a/src/tags/interrupt_tags.rs
+++ b/src/tags/interrupt_tags.rs
@@ -1,19 +1,17 @@
 use std::io::Write;
 
-use liquid_error::Result;
-
-use compiler::Language;
-use compiler::ParseTag;
-use compiler::TagReflection;
-use compiler::TagTokenIter;
-use interpreter::Renderable;
-use interpreter::{Context, Interrupt};
+use liquid_core::interpreter::Interrupt;
+use liquid_core::Context;
+use liquid_core::Language;
+use liquid_core::Renderable;
+use liquid_core::Result;
+use liquid_core::{ParseTag, TagReflection, TagTokenIter};
 
 #[derive(Copy, Clone, Debug)]
 struct Break;
 
 impl Renderable for Break {
-    fn render_to(&self, _writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, _writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         context.interrupt_mut().set_interrupt(Interrupt::Break);
         Ok(())
     }
@@ -41,7 +39,7 @@ impl TagReflection for BreakTag {
 impl ParseTag for BreakTag {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
+        mut arguments: TagTokenIter<'_>,
         _options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         // no arguments should be supplied, trying to supply them is an error
@@ -58,7 +56,7 @@ impl ParseTag for BreakTag {
 struct Continue;
 
 impl Renderable for Continue {
-    fn render_to(&self, _writer: &mut dyn Write, context: &mut Context) -> Result<()> {
+    fn render_to(&self, _writer: &mut dyn Write, context: &mut Context<'_>) -> Result<()> {
         context.interrupt_mut().set_interrupt(Interrupt::Continue);
         Ok(())
     }
@@ -86,7 +84,7 @@ impl TagReflection for ContinueTag {
 impl ParseTag for ContinueTag {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
+        mut arguments: TagTokenIter<'_>,
         _options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         // no arguments should be supplied, trying to supply them is an error
@@ -102,9 +100,11 @@ impl ParseTag for ContinueTag {
 #[cfg(test)]
 mod test {
     use super::*;
-    use compiler;
-    use interpreter;
-    use tags;
+
+    use liquid_core::compiler;
+    use liquid_core::interpreter;
+
+    use crate::tags;
 
     fn options() -> Language {
         let mut options = Language::default();
diff --git a/src/tags/raw_block.rs b/src/tags/raw_block.rs
index b4be586..8770064 100644
--- a/src/tags/raw_block.rs
+++ b/src/tags/raw_block.rs
@@ -1,14 +1,11 @@
 use std::io::Write;
 
-use liquid_error::{Result, ResultLiquidReplaceExt};
-
-use compiler::BlockReflection;
-use compiler::Language;
-use compiler::ParseBlock;
-use compiler::TagBlock;
-use compiler::TagTokenIter;
-use interpreter::Context;
-use interpreter::Renderable;
+use liquid_core::error::ResultLiquidReplaceExt;
+use liquid_core::Context;
+use liquid_core::Language;
+use liquid_core::Renderable;
+use liquid_core::Result;
+use liquid_core::{BlockReflection, ParseBlock, TagBlock, TagTokenIter};
 
 #[derive(Clone, Debug)]
 struct RawT {
@@ -16,7 +13,7 @@ struct RawT {
 }
 
 impl Renderable for RawT {
-    fn render_to(&self, writer: &mut dyn Write, _context: &mut Context) -> Result<()> {
+    fn render_to(&self, writer: &mut dyn Write, _context: &mut Context<'_>) -> Result<()> {
         write!(writer, "{}", self.content).replace("Failed to render")?;
         Ok(())
     }
@@ -48,8 +45,8 @@ impl BlockReflection for RawBlock {
 impl ParseBlock for RawBlock {
     fn parse(
         &self,
-        mut arguments: TagTokenIter,
-        mut tokens: TagBlock,
+        mut arguments: TagTokenIter<'_>,
+        mut tokens: TagBlock<'_, '_>,
         _options: &Language,
     ) -> Result<Box<dyn Renderable>> {
         // no arguments should be supplied, trying to supply them is an error
@@ -69,8 +66,9 @@ impl ParseBlock for RawBlock {
 #[cfg(test)]
 mod test {
     use super::*;
-    use compiler;
-    use interpreter;
+
+    use liquid_core::compiler;
+    use liquid_core::interpreter;
 
     fn options() -> Language {
         let mut options = Language::default();
diff --git a/src/template.rs b/src/template.rs
index b72ae83..de856b1 100644
--- a/src/template.rs
+++ b/src/template.rs
@@ -1,10 +1,10 @@
 use std::io::Write;
 use std::sync;
 
-use liquid_error::Result;
-use liquid_interpreter as interpreter;
-use liquid_interpreter::PartialStore;
-use liquid_interpreter::Renderable;
+use liquid_core::error::Result;
+use liquid_core::interpreter;
+use liquid_core::interpreter::PartialStore;
+use liquid_core::interpreter::Renderable;
 
 pub struct Template {
     pub(crate) template: interpreter::Template,
@@ -13,7 +13,7 @@ pub struct Template {
 
 impl Template {
     /// Renders an instance of the Template, using the given globals.
-    pub fn render(&self, globals: &dyn liquid_value::ObjectView) -> Result<String> {
+    pub fn render(&self, globals: &dyn crate::ObjectView) -> Result<String> {
         const BEST_GUESS: usize = 10_000;
         let mut data = Vec::with_capacity(BEST_GUESS);
         self.render_to(&mut data, globals)?;
@@ -22,11 +22,7 @@ impl Template {
     }
 
     /// Renders an instance of the Template, using the given globals.
-    pub fn render_to(
-        &self,
-        writer: &mut dyn Write,
-        globals: &dyn liquid_value::ObjectView,
-    ) -> Result<()> {
+    pub fn render_to(&self, writer: &mut dyn Write, globals: &dyn crate::ObjectView) -> Result<()> {
         let context = interpreter::ContextBuilder::new().set_globals(globals);
         let context = match self.partials {
             Some(ref partials) => context.set_partials(partials.as_ref()),


Test patch:
diff --git a/tests/conformance.rs b/tests/conformance.rs
index deaee75..81d3507 100644
--- a/tests/conformance.rs
+++ b/tests/conformance.rs
@@ -1,11 +1,5 @@
-extern crate chrono;
-extern crate liquid;
-extern crate regex;
-extern crate serde_yaml;
-
 #[macro_use]
-extern crate liquid_value;
-extern crate liquid_error;
+extern crate liquid_core;
 
 #[macro_use]
 mod test_helper;
diff --git a/tests/conformance_ruby/assign_test.rs b/tests/conformance_ruby/assign_test.rs
index 00017bd..913c14e 100644
--- a/tests/conformance_ruby/assign_test.rs
+++ b/tests/conformance_ruby/assign_test.rs
@@ -11,7 +11,7 @@ fn test_assign_with_hyphen_in_variable_name() {
         .unwrap()
         .parse(template_source)
         .unwrap();
-    let rendered = template.render(&liquid::value::Object::default()).unwrap();
+    let rendered = template.render(&liquid::Object::default()).unwrap();
 
     assert_eq!("Print this-thing", rendered.trim());
 }
diff --git a/tests/conformance_ruby/capture_test.rs b/tests/conformance_ruby/capture_test.rs
index 5f9acd2..fc6a0fa 100644
--- a/tests/conformance_ruby/capture_test.rs
+++ b/tests/conformance_ruby/capture_test.rs
@@ -20,7 +20,7 @@ fn test_capture_with_hyphen_in_variable_name() {
         .unwrap()
         .parse(template_source)
         .unwrap();
-    let rendered = template.render(&liquid::value::Object::default()).unwrap();
+    let rendered = template.render(&liquid::Object::default()).unwrap();
 
     assert_eq!("Print this-thing", rendered.trim());
 }
@@ -42,7 +42,7 @@ fn test_capture_to_variable_from_outer_scope_if_existing() {
         .unwrap()
         .parse(template_source)
         .unwrap();
-    let rendered = template.render(&liquid::value::Object::default()).unwrap();
+    let rendered = template.render(&liquid::Object::default()).unwrap();
 
     assert_eq!("test-string", rendered.trim());
 }
@@ -63,7 +63,7 @@ fn test_assigning_from_capture() {
         .unwrap()
         .parse(template_source)
         .unwrap();
-    let rendered = template.render(&liquid::value::Object::default()).unwrap();
+    let rendered = template.render(&liquid::Object::default()).unwrap();
 
     assert_eq!("3-3", rendered.trim());
 }
diff --git a/tests/conformance_ruby/filter_test.rs b/tests/conformance_ruby/filter_test.rs
index 4fb83a6..ececc39 100644
--- a/tests/conformance_ruby/filter_test.rs
+++ b/tests/conformance_ruby/filter_test.rs
@@ -1,9 +1,7 @@
-use liquid::compiler::Filter;
-use liquid::derive::*;
-use liquid::error::Result;
-use liquid::interpreter::Context;
-use liquid::value::Value;
-use liquid::value::ValueView;
+use liquid_core::Context;
+use liquid_core::Result;
+use liquid_core::{Display_filter, Filter, FilterReflection, ParseFilter};
+use liquid_core::{Value, ValueView};
 
 #[derive(Clone, ParseFilter, FilterReflection)]
 #[filter(name = "money", description = "tests helper", parsed(MoneyFilter))]
@@ -14,7 +12,7 @@ pub struct MoneyFilterParser;
 pub struct MoneyFilter;
 
 impl Filter for MoneyFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         Ok(Value::scalar(format!(" {}$ ", input.render())))
     }
 }
@@ -32,7 +30,7 @@ pub struct MoneyWithUnderscoreFilterParser;
 pub struct MoneyWithUnderscoreFilter;
 
 impl Filter for MoneyWithUnderscoreFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         Ok(Value::scalar(format!(" {}$ ", input.render())))
     }
 }
@@ -58,7 +56,7 @@ pub struct SubstituteFilterParser;
 pub struct SubstituteFilter;
 
 impl Filter for SubstituteFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         Ok(Value::scalar(format!(
             "No keyword argument support: {}",
             input.render()
diff --git a/tests/conformance_ruby/output_test.rs b/tests/conformance_ruby/output_test.rs
index 68792f3..b2a1b80 100644
--- a/tests/conformance_ruby/output_test.rs
+++ b/tests/conformance_ruby/output_test.rs
@@ -1,11 +1,8 @@
-use liquid::compiler::Filter;
-use liquid::compiler::FilterParameters;
-use liquid::derive::*;
-use liquid::error::Result;
-use liquid::interpreter::Context;
-use liquid::interpreter::Expression;
-use liquid::value::Value;
-use liquid::value::ValueView;
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::{Display_filter, Filter, FilterParameters, FilterReflection, ParseFilter};
+use liquid_core::{Value, ValueView};
 
 #[derive(Clone, ParseFilter, FilterReflection)]
 #[filter(
@@ -20,7 +17,7 @@ pub struct MakeFunnyFilterParser;
 pub struct MakeFunnyFilter;
 
 impl Filter for MakeFunnyFilter {
-    fn evaluate(&self, _input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, _input: &Value, _context: &Context<'_>) -> Result<Value> {
         Ok(Value::scalar("LOL"))
     }
 }
@@ -38,7 +35,7 @@ pub struct CiteFunnyFilterParser;
 pub struct CiteFunnyFilter;
 
 impl Filter for CiteFunnyFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         Ok(Value::scalar(format!("LOL: {}", input.render())))
     }
 }
@@ -66,7 +63,7 @@ pub struct AddSmileyFilter {
 }
 
 impl Filter for AddSmileyFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
         let smiley = args.smiley.unwrap_or(":-)".into()).to_string();
         Ok(Value::scalar(format!("{} {}", input.render(), smiley)))
@@ -99,7 +96,7 @@ pub struct AddTagFilter {
 }
 
 impl Filter for AddTagFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let tag = args.tag.unwrap_or("p".into()).to_string();
@@ -127,7 +124,7 @@ pub struct ParagraphFilterParser;
 pub struct ParagraphFilter;
 
 impl Filter for ParagraphFilter {
-    fn evaluate(&self, input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, _context: &Context<'_>) -> Result<Value> {
         Ok(Value::scalar(format!("<p>{}</p>", input.render())))
     }
 }
@@ -155,7 +152,7 @@ pub struct LinkToFilter {
 }
 
 impl Filter for LinkToFilter {
-    fn evaluate(&self, input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let name = input;
@@ -180,7 +177,7 @@ fn liquid() -> liquid::Parser {
         .unwrap()
 }
 
-fn assigns() -> liquid::value::Object {
+fn assigns() -> liquid::Object {
     o!({
       "best_cars": "bmw",
       "car": { "bmw": "good", "gm": "bad" }
diff --git a/tests/conformance_ruby/tags/include_tag_test.rs b/tests/conformance_ruby/tags/include_tag_test.rs
index 7ab2910..0f3c246 100644
--- a/tests/conformance_ruby/tags/include_tag_test.rs
+++ b/tests/conformance_ruby/tags/include_tag_test.rs
@@ -1,6 +1,6 @@
 use std::borrow;
 
-use liquid::value::ValueView;
+use liquid::ValueView;
 
 #[derive(Default, Debug, Clone, Copy)]
 struct TestFileSystem;
diff --git a/tests/conformance_ruby/variable_test.rs b/tests/conformance_ruby/variable_test.rs
index c6baeaf..03493de 100644
--- a/tests/conformance_ruby/variable_test.rs
+++ b/tests/conformance_ruby/variable_test.rs
@@ -1,4 +1,4 @@
-use liquid::value::ValueView;
+use liquid::ValueView;
 
 #[test]
 fn test_simple_variable() {
diff --git a/tests/derive_macros.rs b/tests/derive_macros.rs
index 82ccff8..eabc76e 100644
--- a/tests/derive_macros.rs
+++ b/tests/derive_macros.rs
@@ -1,7 +1,7 @@
-extern crate liquid;
+use liquid;
 
-use liquid::compiler::FilterReflection;
 use liquid::{Parser, ParserBuilder};
+use liquid_core::compiler::FilterReflection;
 
 mod derive_macros_test_filters;
 
@@ -32,7 +32,7 @@ pub fn test_derive_positional_filter_ok() {
         "<pos1: true; pos2: 0>"
     );
 
-    let globals = liquid::value::Object::new();
+    let globals = liquid::Object::new();
     let rendered = template.render(&globals).unwrap();
 
     assert_eq!(rendered, expected);
@@ -47,7 +47,7 @@ pub fn test_derive_positional_filter_err() {
     assert!(parser.parse("{{ 0 | pos:named:4 }}\n").is_err());
     assert!(parser.parse("{{ 0 | pos:32, pos2:42 }}\n").is_err());
 
-    let globals = liquid::value::Object::new();
+    let globals = liquid::Object::new();
 
     assert!(parser
         .parse("{{ 0 | pos: \"str\", \"str\" }}\n")
@@ -95,7 +95,7 @@ pub fn test_derive_keyword_filter_ok() {
         "<required: false>"
     );
 
-    let globals = liquid::value::Object::new();
+    let globals = liquid::Object::new();
     let rendered = template.render(&globals).unwrap();
 
     assert_eq!(rendered, expected);
@@ -111,7 +111,7 @@ pub fn test_derive_keyword_filter_err() {
         .parse("{{ 0 | kw: required: true, optional:\"str\", 5 }}\n")
         .is_err());
 
-    let globals = liquid::value::Object::new();
+    let globals = liquid::Object::new();
 
     assert!(parser
         .parse("{{ 0 | kw: required:\"str\" }}\n")
@@ -158,7 +158,7 @@ pub fn test_derive_mixed_filter_ok() {
         "<a: 5; b: false; c: 4.3, d: 2019-02-08 15:34:25 -0800, e: 2019-02-08, f: str, type: 0>"
     );
 
-    let globals = liquid::value::Object::new();
+    let globals = liquid::Object::new();
     let rendered = template.render(&globals).unwrap();
 
     assert_eq!(rendered, expected);
@@ -227,7 +227,7 @@ pub fn test_derive_parameterless_filter_ok() {
     let template = parser.parse("{{ 0 | no_args }}").unwrap();
     let expected = "<>";
 
-    let globals = liquid::value::Object::new();
+    let globals = liquid::Object::new();
     let rendered = template.render(&globals).unwrap();
 
     assert_eq!(rendered, expected);
@@ -254,7 +254,7 @@ pub fn test_derive_parameterless_filter_reflection() {
 
 #[test]
 pub fn test_derive_stateful_filter() {
-    let globals = liquid::value::Object::new();
+    let globals = liquid::Object::new();
 
     let filter = derive_macros_test_filters::TestStatefulFilterParser::new();
 
diff --git a/tests/derive_macros_test_filters/keyword.rs b/tests/derive_macros_test_filters/keyword.rs
index 468c511..90032b9 100644
--- a/tests/derive_macros_test_filters/keyword.rs
+++ b/tests/derive_macros_test_filters/keyword.rs
@@ -1,10 +1,10 @@
-extern crate liquid;
-use liquid::compiler::{Filter, FilterParameters};
-use liquid::derive::*;
-use liquid::error::Result;
-use liquid::interpreter::Context;
-use liquid::interpreter::Expression;
-use liquid::value::Value;
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::Value;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
 
 #[derive(Debug, FilterParameters)]
 struct TestKeywordFilterParameters {
@@ -40,7 +40,7 @@ pub struct TestKeywordFilter {
 }
 
 impl Filter for TestKeywordFilter {
-    fn evaluate(&self, _input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, _input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let required = args.required;
diff --git a/tests/derive_macros_test_filters/mixed.rs b/tests/derive_macros_test_filters/mixed.rs
index 5732e00..ce72ad4 100644
--- a/tests/derive_macros_test_filters/mixed.rs
+++ b/tests/derive_macros_test_filters/mixed.rs
@@ -1,10 +1,10 @@
-extern crate liquid;
-use liquid::compiler::{Filter, FilterParameters};
-use liquid::derive::*;
-use liquid::error::Result;
-use liquid::interpreter::Context;
-use liquid::interpreter::Expression;
-use liquid::value::Value;
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::Value;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
 
 // Colision with FilterParameters' evaluated struct.
 #[allow(dead_code)]
@@ -52,7 +52,7 @@ pub struct TestMixedFilter {
 }
 
 impl Filter for TestMixedFilter {
-    fn evaluate(&self, _input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, _input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let a = args.a.map(|i| i.to_string()).unwrap_or("None".to_string());
diff --git a/tests/derive_macros_test_filters/parameterless.rs b/tests/derive_macros_test_filters/parameterless.rs
index 8b03d10..a62ef75 100644
--- a/tests/derive_macros_test_filters/parameterless.rs
+++ b/tests/derive_macros_test_filters/parameterless.rs
@@ -1,9 +1,7 @@
-extern crate liquid;
-use liquid::compiler::Filter;
-use liquid::derive::*;
-use liquid::error::Result;
-use liquid::interpreter::Context;
-use liquid::value::Value;
+use liquid_core::Context;
+use liquid_core::Result;
+use liquid_core::Value;
+use liquid_core::{Display_filter, Filter, FilterReflection, ParseFilter};
 
 #[derive(Clone, ParseFilter, FilterReflection)]
 #[filter(
@@ -18,7 +16,7 @@ pub struct TestParameterlessFilterParser;
 pub struct TestParameterlessFilter;
 
 impl Filter for TestParameterlessFilter {
-    fn evaluate(&self, _input: &Value, _context: &Context) -> Result<Value> {
+    fn evaluate(&self, _input: &Value, _context: &Context<'_>) -> Result<Value> {
         let result = "<>";
 
         Ok(Value::scalar(result))
diff --git a/tests/derive_macros_test_filters/positional.rs b/tests/derive_macros_test_filters/positional.rs
index 1e0374b..c9f9380 100644
--- a/tests/derive_macros_test_filters/positional.rs
+++ b/tests/derive_macros_test_filters/positional.rs
@@ -1,10 +1,10 @@
-extern crate liquid;
-use liquid::compiler::{Filter, FilterParameters};
-use liquid::derive::*;
-use liquid::error::Result;
-use liquid::interpreter::Context;
-use liquid::interpreter::Expression;
-use liquid::value::Value;
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::Value;
+use liquid_core::{
+    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
+};
 
 #[derive(Debug, FilterParameters)]
 struct TestPositionalFilterParameters {
@@ -35,7 +35,7 @@ pub struct TestPositionalFilter {
 }
 
 impl Filter for TestPositionalFilter {
-    fn evaluate(&self, _input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, _input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let pos1 = args.pos1.to_kstr();
diff --git a/tests/derive_macros_test_filters/stateful.rs b/tests/derive_macros_test_filters/stateful.rs
index 3b0eaad..31b5b6f 100644
--- a/tests/derive_macros_test_filters/stateful.rs
+++ b/tests/derive_macros_test_filters/stateful.rs
@@ -1,10 +1,9 @@
-extern crate liquid;
-use liquid::compiler::{Filter, FilterArguments, FilterParameters, ParseFilter};
-use liquid::derive::*;
-use liquid::error::Result;
-use liquid::interpreter::Context;
-use liquid::interpreter::Expression;
-use liquid::value::Value;
+use liquid_core::compiler::FilterArguments;
+use liquid_core::Context;
+use liquid_core::Expression;
+use liquid_core::Result;
+use liquid_core::Value;
+use liquid_core::{Display_filter, Filter, FilterParameters, FilterReflection, ParseFilter};
 
 #[derive(Clone, Copy, Debug)]
 enum Mood {
@@ -46,14 +45,14 @@ impl TestStatefulFilterParser {
 }
 
 impl ParseFilter for TestStatefulFilterParser {
-    fn parse(&self, arguments: FilterArguments) -> Result<Box<dyn Filter>> {
+    fn parse(&self, arguments: FilterArguments<'_>) -> Result<Box<dyn Filter>> {
         let args = TestStatefulFilterParameters::from_args(arguments)?;
         let state = self.state;
 
         Ok(Box::new(TestStatefulFilter { args, state }))
     }
 
-    fn reflection(&self) -> &dyn liquid::compiler::FilterReflection {
+    fn reflection(&self) -> &dyn liquid_core::FilterReflection {
         self
     }
 }
@@ -67,7 +66,7 @@ pub struct TestStatefulFilter {
 }
 
 impl Filter for TestStatefulFilter {
-    fn evaluate(&self, _input: &Value, context: &Context) -> Result<Value> {
+    fn evaluate(&self, _input: &Value, context: &Context<'_>) -> Result<Value> {
         let args = self.args.evaluate(context)?;
 
         let result = match self.state {
diff --git a/tests/filters.rs b/tests/filters.rs
index 15a57e7..ffc63b5 100644
--- a/tests/filters.rs
+++ b/tests/filters.rs
@@ -1,15 +1,11 @@
-extern crate liquid;
-extern crate serde_yaml;
+use liquid;
 
 #[test]
 pub fn upcase() {
     let text = "{{ text | upcase}}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: hello
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "text": "hello",
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -22,12 +18,9 @@ text: hello
 #[test]
 pub fn downcase() {
     let text = "{{ text | downcase}}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: HELLO tHeRe
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "text": "HELLO tHeRe",
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -40,12 +33,9 @@ text: HELLO tHeRe
 #[test]
 pub fn capitalize() {
     let text = "{{ text | capitalize}}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: hello world
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "text": "hello world",
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -59,12 +49,9 @@ text: hello world
 #[cfg(feature = "extra-filters")]
 pub fn pluralize_none() {
     let text = "{{ count | pluralize: 'one', 'many'}}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-count: 0
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "count": 0,
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .extra_filters()
         .build()
@@ -79,12 +66,9 @@ count: 0
 #[cfg(feature = "extra-filters")]
 pub fn pluralize_singular() {
     let text = "{{ count | pluralize: 'one', 'many'}}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-count: 1
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "count": 1,
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .extra_filters()
         .build()
@@ -99,12 +83,9 @@ count: 1
 #[cfg(feature = "extra-filters")]
 pub fn pluralize_plural() {
     let text = "{{ count | pluralize: 'one', 'many'}}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-count: 10
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "count": 10,
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .extra_filters()
         .build()
@@ -118,12 +99,9 @@ count: 10
 #[test]
 pub fn minus() {
     let text = "{{ num | minus : 2 }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-num: 4
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "num": 4,
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -136,12 +114,9 @@ num: 4
 #[test]
 pub fn plus() {
     let text = "{{ num | plus : 2 }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-num: 4
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "num": 4,
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -154,12 +129,9 @@ num: 4
 #[test]
 pub fn minus_error() {
     let text = "{{ num | minus }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-num: 4
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "num": 4,
+    });
     let output = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -172,12 +144,9 @@ num: 4
 #[test]
 pub fn first_numeric_array() {
     let text = "{{ nums | first }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-nums: [12, 1]
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "nums": [12, 1],
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -190,12 +159,9 @@ nums: [12, 1]
 #[test]
 pub fn first_string_array() {
     let text = "{{ nums | first }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-nums: ["first", "second"]
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "nums": ["first", "second"],
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -208,12 +174,9 @@ nums: ["first", "second"]
 #[test]
 pub fn first_char() {
     let text = "{{ nums | first }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-nums: first
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "nums": "first",
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -226,12 +189,9 @@ nums: first
 #[test]
 pub fn last_numeric_array() {
     let text = "{{ nums | last }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-nums: [12, 1]
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "nums": [12, 1],
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -244,12 +204,9 @@ nums: [12, 1]
 #[test]
 pub fn last_string_array() {
     let text = "{{ nums | last }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-nums: ["first", "second"]
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "nums": ["first", "second"],
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -262,12 +219,9 @@ nums: ["first", "second"]
 #[test]
 pub fn last_char() {
     let text = "{{ nums | last }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-nums: second
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "nums": "second",
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -280,12 +234,9 @@ nums: second
 #[test]
 pub fn replace_first() {
     let text = "{{ text | replace_first: 'bar', 'foo' }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: bar2bar
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "text": "bar2bar",
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -298,12 +249,9 @@ text: bar2bar
 #[test]
 pub fn replace() {
     let text = "{{ text | replace: 'bar', 'foo' }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: bar2bar
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "text": "bar2bar",
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -316,12 +264,9 @@ text: bar2bar
 #[test]
 pub fn prepend_constant() {
     let text = "{{ text | prepend: 'fifo' }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: bar2bar
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "text": "bar2bar",
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -334,13 +279,10 @@ text: bar2bar
 #[test]
 pub fn prepend_variable() {
     let text = "{{ text | prepend: myvar }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: bar2bar
-myvar: fifo
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "text": "bar2bar",
+        "myvar": "fifo",
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -353,12 +295,9 @@ myvar: fifo
 #[test]
 pub fn append() {
     let text = "{{ text | append: 'lifo' }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: roobarb
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "text": "roobarb",
+    });
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -375,7 +314,7 @@ text: roobarb
 pub fn split_with_comma() {
     let text = "{% assign beatles = \"John, Paul, George, Ringo\" | split: \", \" %}{% for member \
                 in beatles %}{{ member }}\n{% endfor %}";
-    let globals: liquid::value::Object = Default::default();
+    let globals = liquid::Object::default();
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -390,7 +329,7 @@ pub fn split_with_comma() {
 pub fn split_no_comma() {
     let text = "{% assign letters = \"a~b~c\" | split:\"~\" %}{% for letter in letters %}LETTER: \
                 {{ letter }}\n{% endfor %}";
-    let globals: liquid::value::Object = Default::default();
+    let globals = liquid::Object::default();
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -404,7 +343,7 @@ pub fn split_no_comma() {
 #[test]
 pub fn split_then_join() {
     let text = "{{ 'a~b~c' | split:'~' | join:', ' }}";
-    let globals: liquid::value::Object = Default::default();
+    let globals = liquid::Object::default();
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -418,7 +357,7 @@ pub fn split_then_join() {
 #[test]
 pub fn slice_one() {
     let text = "{{ '0123456' | slice: 2 }}";
-    let globals: liquid::value::Object = Default::default();
+    let globals = liquid::Object::default();
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -432,7 +371,7 @@ pub fn slice_one() {
 #[test]
 pub fn slice_negative() {
     let text = "{{ '6543210' | slice: -4, 3 }}";
-    let globals: liquid::value::Object = Default::default();
+    let globals = liquid::Object::default();
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -446,7 +385,7 @@ pub fn slice_negative() {
 // Slicing with overflow should fit to string size
 pub fn slice_overflow() {
     let text = "{{ 'xx0123456' | slice: 2, 11 }}";
-    let globals: liquid::value::Object = Default::default();
+    let globals = liquid::Object::default();
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -460,7 +399,7 @@ pub fn slice_overflow() {
 // Slicing empty string should not fail
 pub fn slice_empty() {
     let text = "{{ '' | slice: 2 }}";
-    let globals: liquid::value::Object = Default::default();
+    let globals = liquid::Object::default();
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -474,7 +413,7 @@ pub fn slice_empty() {
 // Split string, sort it then re-join
 pub fn split_sort_join() {
     let text = "{{ 'zebra, octopus, giraffe, Sally Snake' | split:', ' | sort | join: ', '}}";
-    let globals: liquid::value::Object = Default::default();
+    let globals = liquid::Object::default();
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -489,8 +428,7 @@ pub fn modulo() {
     let text = "{{ num | modulo: 2 }}";
     let samples = [(4_f64, "0"), (3_f64, "1"), (5.1, "1.0999999999999996")];
     for t in &samples {
-        let globals: liquid::value::Object =
-            serde_yaml::from_str(&format!("num: {}", t.0)).unwrap();
+        let globals = liquid::object!({"num": t.0});
         let template = liquid::ParserBuilder::with_liquid()
             .build()
             .unwrap()
@@ -513,8 +451,7 @@ pub fn escape() {
         ("&etc.", "&amp;etc."),
     ];
     for t in &samples {
-        let mut globals = liquid::value::Object::new();
-        globals.insert("var".into(), liquid::value::Value::scalar(t.0));
+        let globals = liquid::object!({"var": t.0});
         let template = liquid::ParserBuilder::with_liquid()
             .build()
             .unwrap()
@@ -537,8 +474,7 @@ pub fn escape_once() {
         ("&lt;&gt;&amp;&#39;&quot;", "&lt;&gt;&amp;&#39;&quot;"),
     ];
     for t in &samples {
-        let mut globals = liquid::value::Object::new();
-        globals.insert("var".into(), liquid::value::Value::scalar(t.0));
+        let globals = liquid::object!({"var": t.0});
         let template = liquid::ParserBuilder::with_liquid()
             .build()
             .unwrap()
@@ -552,12 +488,7 @@ pub fn escape_once() {
 #[test]
 pub fn remove_first_constant() {
     let text = "{{ text | remove_first: 'bar' }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: bar2bar
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({"text": "bar2bar"});
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -570,13 +501,7 @@ text: bar2bar
 #[test]
 pub fn remove_first_variable() {
     let text = "{{ text | remove_first: myvar }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: bar2bar
-myvar: bar
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({"text": "bar2bar", "myvar": "bar"});
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -589,12 +514,7 @@ myvar: bar
 #[test]
 pub fn remove() {
     let text = "{{ text | remove: 'bar' }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: bar2bar
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({"text": "bar2bar"});
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -607,12 +527,7 @@ text: bar2bar
 #[test]
 pub fn strip_html() {
     let text = "{{ text | strip_html }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: "<!-- <b> Comment -->Lorem <a>ipsum </b>dolor"
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({"text": "<!-- <b> Comment -->Lorem <a>ipsum </b>dolor"});
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -625,12 +540,7 @@ text: "<!-- <b> Comment -->Lorem <a>ipsum </b>dolor"
 #[test]
 pub fn truncatewords() {
     let text = "{{ text | truncatewords: 1, '...' }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: "first second third"
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({"text": "first second third"});
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -643,12 +553,7 @@ text: "first second third"
 #[test]
 pub fn default_use() {
     let text = "{{ text | default: 'bar' }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: false
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({"text": false});
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -661,12 +566,7 @@ text: false
 #[test]
 pub fn default_pass() {
     let text = "{{ text | default: 'bar' }}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-text: foo
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({"text": "foo"});
     let template = liquid::ParserBuilder::with_liquid()
         .build()
         .unwrap()
@@ -679,13 +579,10 @@ text: foo
 #[test]
 fn test_compact() {
     let text = "{{hashes | compact: 'a' | map: 'a' | join}}";
-    let globals: liquid::value::Object = serde_yaml::from_str(
-        r#"
-words: ["a", null, "b", null, "c"]
-hashes: [{"a": "A"}, {"a": null}, {"a": "C"}, {}]
-"#,
-    )
-    .unwrap();
+    let globals = liquid::object!({
+        "words": ["a", liquid_core::Value::Nil, "b", liquid_core::Value::Nil, "c"],
+        "hashes": [{"a": "A"}, {"a": liquid_core::Value::Nil}, {"a": "C"}, {}],
+    });
 
     let template = liquid::ParserBuilder::with_liquid()
         .build()
diff --git a/tests/fixtures.rs b/tests/fixtures.rs
index 5470ca3..d92ed7d 100644
--- a/tests/fixtures.rs
+++ b/tests/fixtures.rs
@@ -1,14 +1,13 @@
 #[macro_use]
 extern crate difference;
-extern crate liquid;
-extern crate serde_yaml;
+use liquid;
 
 use std::fs::File;
 use std::io::Read;
 
 use liquid::*;
 
-fn compare_by_file(name: &str, globals: &value::Object) {
+fn compare_by_file(name: &str, globals: &Object) {
     let input_file = format!("tests/fixtures/input/{}.txt", name);
     let output_file = format!("tests/fixtures/output/{}.txt", name);
 
@@ -42,42 +41,34 @@ fn compare_by_file(name: &str, globals: &value::Object) {
 
 #[test]
 pub fn chained_filters() {
-    let globals: value::Object = serde_yaml::from_str(
-        r#"
-foo: foofoo
-"#,
-    )
-    .unwrap();
+    let globals = object!({
+        "foo": "foofoo",
+    });
     compare_by_file("chained_filters", &globals);
 }
 
 #[test]
 pub fn example() {
-    let globals: value::Object = serde_yaml::from_str(
-        r#"
-num: 5
-numTwo: 6
-"#,
-    )
-    .unwrap();
+    let globals = object!({
+        "num": 5,
+        "numTwo": 6
+    });
     compare_by_file("example", &globals);
 }
 
 #[test]
 pub fn include() {
-    let mut globals: value::Object = Default::default();
-    globals.insert("num".into(), value::Value::scalar(5f64));
-    globals.insert("numTwo".into(), value::Value::scalar(10f64));
+    let globals = object!({
+        "num": 5f64,
+        "numTwo": 10f64,
+    });
     compare_by_file("include", &globals);
 }
 
 #[test]
 pub fn include_with_context() {
-    let globals: value::Object = serde_yaml::from_str(
-        r#"
-content: "hello, world!"
-"#,
-    )
-    .unwrap();
+    let globals = object!({
+        "content": "hello, world!",
+    });
     compare_by_file("include_with_context", &globals);
 }
diff --git a/tests/multithreading.rs b/tests/multithreading.rs
index 9d72956..2261ece 100644
--- a/tests/multithreading.rs
+++ b/tests/multithreading.rs
@@ -1,7 +1,6 @@
 #[macro_use]
 extern crate difference;
-extern crate liquid;
-extern crate serde_yaml;
+use liquid;
 
 use std::fs::File;
 use std::io::Read;
@@ -26,14 +25,10 @@ pub fn pass_between_threads() {
         let template = Arc::clone(&template);
         let output_file = format!("tests/fixtures/output/example_mt{}.txt", counter + 1);
         handles.push(thread::spawn(move || {
-            let globals: liquid::value::Object = serde_yaml::from_str(&format!(
-                r#"
-num: {}
-numTwo: {}
-"#,
-                num1, num2
-            ))
-            .unwrap();
+            let globals = liquid::object!({
+                "num": num1,
+                "numTwo": num2,
+            });
             let output = template.render(&globals).unwrap();
 
             let mut comp = String::new();
diff --git a/tests/parse_file.rs b/tests/parse_file.rs
index 51d0d90..68e58a3 100644
--- a/tests/parse_file.rs
+++ b/tests/parse_file.rs
@@ -1,13 +1,11 @@
 #[macro_use]
 extern crate difference;
-extern crate liquid;
-extern crate serde_yaml;
 
 use liquid::*;
 use std::fs::File;
 use std::io::Read;
 
-fn compare_by_file(name: &str, globals: &value::Object) {
+fn compare_by_file(name: &str, globals: &Object) {
     let input_file = format!("tests/fixtures/input/{}.txt", name);
     let output_file = format!("tests/fixtures/output/{}.txt", name);
 
@@ -41,12 +39,9 @@ pub fn error_on_nonexistent_file() {
 
 #[test]
 pub fn example_by_file() {
-    let globals: value::Object = serde_yaml::from_str(
-        r#"
-num: 5
-numTwo: 6
-"#,
-    )
-    .unwrap();
+    let globals = object!({
+        "num": 5,
+        "numTwo": 6
+    });
     compare_by_file("example", &globals);
 }
diff --git a/tests/syntax.rs b/tests/syntax.rs
index 1e1ed7e..88c3ac5 100644
--- a/tests/syntax.rs
+++ b/tests/syntax.rs
@@ -1,6 +1,5 @@
 #[macro_use]
 extern crate difference;
-extern crate liquid;
 
 use liquid::*;
 
@@ -15,7 +14,7 @@ fn compare(input: &str, expected: &str) {
         .parse(&input)
         .unwrap();
 
-    let output = template.render(&value::Object::default()).unwrap();
+    let output = template.render(&Object::default()).unwrap();
 
     assert_diff!(&expected, &output, " ", 0);
 }
diff --git a/tests/test_helper.rs b/tests/test_helper.rs
index 6617fd0..cfcb1d8 100644
--- a/tests/test_helper.rs
+++ b/tests/test_helper.rs
@@ -1,17 +1,15 @@
-extern crate chrono;
-extern crate liquid;
-extern crate regex;
+use liquid_core;
 
-pub use liquid::value::Value::Nil;
+pub use liquid_core::Value::Nil;
 
 #[allow(dead_code)]
-pub fn date(y: i32, m: u32, d: u32) -> liquid::value::Value {
-    use liquid::value::{Date, Value};
+pub fn date(y: i32, m: u32, d: u32) -> liquid_core::Value {
+    use liquid_core::value::{Date, Value};
     Value::scalar(Date::from_ymd(y, m, d))
 }
 
 #[allow(dead_code)]
-pub fn with_time(_time: &str) -> liquid::value::Value {
+pub fn with_time(_time: &str) -> liquid_core::Value {
     Nil
 }
 
@@ -19,7 +17,7 @@ pub fn with_time(_time: &str) -> liquid::value::Value {
 #[macro_export]
 macro_rules! v {
     ($($value:tt)+) => {
-        value!($($value)+)
+        ::liquid_core::value::value!($($value)+)
     };
 }
 
@@ -27,7 +25,7 @@ macro_rules! v {
 #[macro_export]
 macro_rules! o {
     ($($value:tt)+) => {
-        object!($($value)+)
+        ::liquid_core::object!($($value)+)
     };
 }
 
@@ -35,7 +33,7 @@ macro_rules! o {
 #[macro_export]
 macro_rules! a {
     ($($value:tt)+) => {
-        array!($($value)+)
+        ::liquid_core::value::array!($($value)+)
     };
 }
 
@@ -46,7 +44,7 @@ macro_rules! assert_template_result {
         assert_template_result!($expected, $template);
     };
     ($expected:expr, $template:expr) => {
-        let assigns = ::liquid::value::Object::default();
+        let assigns = ::liquid_core::Object::default();
         assert_template_result!($expected, $template, assigns);
     };
     ($expected:expr, $template:expr, $assigns: expr, ) => {
@@ -123,7 +121,7 @@ macro_rules! assert_render_error {
         assert_render_error!($template);
     };
     ($template:expr) => {
-        let assigns = ::liquid::value::Object::default();
+        let assigns = ::liquid::Object::default();
         assert_render_error!($template, assigns);
     };
     ($template:expr, $assigns: expr, ) => {
@@ -146,14 +144,14 @@ macro_rules! filters {
         filters!($a, $b, )
     }};
     ($a:ident, $b:expr, $($c:expr),*) => {{
-        let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+        let positional = Box::new(vec![$(::liquid_core::Expression::Literal($c)),*].into_iter());
         let keyword = Box::new(Vec::new().into_iter());
-        let args = ::liquid::compiler::FilterArguments { positional, keyword };
+        let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-        let context = ::liquid::interpreter::Context::default();
+        let context = ::liquid_core::Context::default();
 
-        let filter = ::liquid::compiler::ParseFilter::parse(&::liquid::filters::std::$a, args).unwrap();
-        ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+        let filter = ::liquid_core::ParseFilter::parse(&::liquid::filters::std::$a, args).unwrap();
+        ::liquid_core::Filter::evaluate(&*filter, &$b, &context).unwrap()
     }};
 }
 
@@ -164,14 +162,14 @@ macro_rules! filters_fail {
         filters_fail!($a, $b, )
     }};
     ($a:ident, $b:expr, $($c:expr),*) => {{
-        let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+        let positional = Box::new(vec![$(::liquid_core::Expression::Literal($c)),*].into_iter());
         let keyword = Box::new(Vec::new().into_iter());
-        let args = ::liquid::compiler::FilterArguments { positional, keyword };
+        let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-        let context = ::liquid::interpreter::Context::default();
+        let context = ::liquid_core::Context::default();
 
-        ::liquid::compiler::ParseFilter::parse(&::liquid::filters::std::$a, args)
-            .and_then(|filter| ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context))
+        ::liquid_core::ParseFilter::parse(&::liquid::filters::std::$a, args)
+            .and_then(|filter| ::liquid_core::Filter::evaluate(&*filter, &$b, &context))
             .unwrap_err()
     }};
 }
@@ -184,14 +182,14 @@ macro_rules! jekyll_filters {
         jekyll_filters!($a, $b, )
     }};
     ($a:ident, $b:expr, $($c:expr),*) => {{
-        let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+        let positional = Box::new(vec![$(::liquid_core::Expression::Literal($c)),*].into_iter());
         let keyword = Box::new(Vec::new().into_iter());
-        let args = ::liquid::compiler::FilterArguments { positional, keyword };
+        let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-        let context = ::liquid::interpreter::Context::default();
+        let context = ::liquid_core::Context::default();
 
-        let filter = ::liquid::compiler::ParseFilter::parse(&::liquid::filters::jekyll::$a, args).unwrap();
-        ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context).unwrap()
+        let filter = ::liquid_core::ParseFilter::parse(&::liquid::filters::jekyll::$a, args).unwrap();
+        ::liquid_core::Filter::evaluate(&*filter, &$b, &context).unwrap()
     }};
 }
 
@@ -203,14 +201,14 @@ macro_rules! jekyll_filters_fail {
         jekyll_filters_fail!($a, $b, )
     }};
     ($a:ident, $b:expr, $($c:expr),*) => {{
-        let positional = Box::new(vec![$(::liquid::interpreter::Expression::Literal($c)),*].into_iter());
+        let positional = Box::new(vec![$(::liquid_core::Expression::Literal($c)),*].into_iter());
         let keyword = Box::new(Vec::new().into_iter());
-        let args = ::liquid::compiler::FilterArguments { positional, keyword };
+        let args = ::liquid_core::compiler::FilterArguments { positional, keyword };
 
-        let context = ::liquid::interpreter::Context::default();
+        let context = ::liquid_core::Context::default();
 
-        ::liquid::compiler::ParseFilter::parse(&::liquid::filters::jekyll::$a, args)
-            .and_then(|filter| ::liquid::compiler::Filter::evaluate(&*filter, &$b, &context))
+        ::liquid_core::ParseFilter::parse(&::liquid::filters::jekyll::$a, args)
+            .and_then(|filter| ::liquid_core::Filter::evaluate(&*filter, &$b, &context))
             .unwrap_err()
     }};
 }