diff --git a/crate_universe/src/rendering.rs b/crate_universe/src/rendering.rs
new file mode 100644
index 0000000..a0570ba
--- /dev/null
+++ b/crate_universe/src/rendering.rs
@@ -0,0 +1,470 @@
+//! Tools for rendering and writing BUILD and other Starlark files
+
+mod template_engine;
+
+use std::collections::BTreeMap;
+use std::fs;
+use std::path::{Path, PathBuf};
+use std::str::FromStr;
+
+use anyhow::{bail, Context as AnyhowContext, Result};
+
+use crate::config::RenderConfig;
+use crate::context::Context;
+use crate::rendering::template_engine::TemplateEngine;
+use crate::splicing::default_splicing_package_crate_id;
+use crate::utils::starlark::Label;
+
+pub struct Renderer {
+    config: RenderConfig,
+    engine: TemplateEngine,
+}
+
+impl Renderer {
+    pub fn new(config: RenderConfig) -> Self {
+        let engine = TemplateEngine::new(&config);
+        Self { config, engine }
+    }
+
+    pub fn render(&self, context: &Context) -> Result<BTreeMap<PathBuf, String>> {
+        let mut output = BTreeMap::new();
+
+        output.extend(self.render_build_files(context)?);
+        output.extend(self.render_crates_module(context)?);
+
+        if let Some(vendor_mode) = &self.config.vendor_mode {
+            match vendor_mode {
+                crate::config::VendorMode::Local => {
+                    // Nothing to do for local vendor crate
+                }
+                crate::config::VendorMode::Remote => {
+                    output.extend(self.render_vendor_support_files(context)?);
+                }
+            }
+        }
+
+        Ok(output)
+    }
+
+    fn render_crates_module(&self, context: &Context) -> Result<BTreeMap<PathBuf, String>> {
+        let module_label = render_module_label(&self.config.crates_module_template, "defs.bzl")
+            .context("Failed to resolve string to module file label")?;
+        let module_build_label =
+            render_module_label(&self.config.crates_module_template, "BUILD.bazel")
+                .context("Failed to resolve string to module file label")?;
+
+        let mut map = BTreeMap::new();
+        map.insert(
+            Renderer::label_to_path(&module_label),
+            self.engine.render_module_bzl(context)?,
+        );
+        map.insert(
+            Renderer::label_to_path(&module_build_label),
+            self.engine.render_module_build_file(context)?,
+        );
+
+        Ok(map)
+    }
+
+    fn render_build_files(&self, context: &Context) -> Result<BTreeMap<PathBuf, String>> {
+        let default_splicing_package_id = default_splicing_package_crate_id();
+        self.engine
+            .render_crate_build_files(context)?
+            .into_iter()
+            // Do not render the default splicing package
+            .filter(|(id, _)| *id != &default_splicing_package_id)
+            // Do not render local packages
+            .filter(|(id, _)| !context.workspace_members.contains_key(id))
+            .map(|(id, content)| {
+                let ctx = &context.crates[id];
+                let label = match render_build_file_template(
+                    &self.config.build_file_template,
+                    &ctx.name,
+                    &ctx.version,
+                ) {
+                    Ok(label) => label,
+                    Err(e) => bail!(e),
+                };
+
+                let filename = Renderer::label_to_path(&label);
+
+                Ok((filename, content))
+            })
+            .collect()
+    }
+
+    fn render_vendor_support_files(&self, context: &Context) -> Result<BTreeMap<PathBuf, String>> {
+        let module_label = render_module_label(&self.config.crates_module_template, "crates.bzl")
+            .context("Failed to resolve string to module file label")?;
+
+        let mut map = BTreeMap::new();
+        map.insert(
+            Renderer::label_to_path(&module_label),
+            self.engine.render_vendor_module_file(context)?,
+        );
+
+        Ok(map)
+    }
+
+    fn label_to_path(label: &Label) -> PathBuf {
+        match &label.package {
+            Some(package) => PathBuf::from(format!("{}/{}", package, label.target)),
+            None => PathBuf::from(&label.target),
+        }
+    }
+}
+
+/// Write a set of [CrateContext][crate::context::CrateContext] to disk.
+pub fn write_outputs(
+    outputs: BTreeMap<PathBuf, String>,
+    out_dir: &Path,
+    dry_run: bool,
+) -> Result<()> {
+    let outputs: BTreeMap<PathBuf, String> = outputs
+        .into_iter()
+        .map(|(path, content)| (out_dir.join(path), content))
+        .collect();
+
+    if dry_run {
+        for (path, content) in outputs {
+            println!(
+                "==============================================================================="
+            );
+            println!("{}", path.display());
+            println!(
+                "==============================================================================="
+            );
+            println!("{}\n", content);
+        }
+    } else {
+        for (path, content) in outputs {
+            // Ensure the output directory exists
+            fs::create_dir_all(
+                path.parent()
+                    .expect("All file paths should have valid directories"),
+            )?;
+
+            fs::write(&path, content.as_bytes())
+                .context(format!("Failed to write file to disk: {}", path.display()))?;
+        }
+    }
+
+    Ok(())
+}
+
+/// Render the Bazel label of a crate
+pub fn render_crate_bazel_label(
+    template: &str,
+    repository_name: &str,
+    name: &str,
+    version: &str,
+    target: &str,
+) -> String {
+    template
+        .replace("{repository}", repository_name)
+        .replace("{name}", name)
+        .replace("{version}", version)
+        .replace("{target}", target)
+}
+
+/// Render the Bazel label of a crate
+pub fn render_crate_bazel_repository(
+    template: &str,
+    repository_name: &str,
+    name: &str,
+    version: &str,
+) -> String {
+    template
+        .replace("{repository}", repository_name)
+        .replace("{name}", name)
+        .replace("{version}", version)
+}
+
+/// Render the Bazel label of a crate
+pub fn render_crate_build_file(template: &str, name: &str, version: &str) -> String {
+    template
+        .replace("{name}", name)
+        .replace("{version}", version)
+}
+
+/// Render the Bazel label of a vendor module label
+pub fn render_module_label(template: &str, name: &str) -> Result<Label> {
+    Label::from_str(&template.replace("{file}", name))
+}
+
+/// Render the Bazel label of a platform triple
+pub fn render_platform_constraint_label(template: &str, triple: &str) -> String {
+    template.replace("{triple}", triple)
+}
+
+fn render_build_file_template(template: &str, name: &str, version: &str) -> Result<Label> {
+    Label::from_str(
+        &template
+            .replace("{name}", name)
+            .replace("{version}", version),
+    )
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    use crate::config::{Config, CrateId, VendorMode};
+    use crate::context::crate_context::{CrateContext, Rule};
+    use crate::context::{BuildScriptAttributes, Context, TargetAttributes};
+    use crate::metadata::Annotations;
+    use crate::test;
+
+    fn mock_render_config() -> RenderConfig {
+        serde_json::from_value(serde_json::json!({
+            "repository_name": "test_rendering"
+        }))
+        .unwrap()
+    }
+
+    fn mock_target_attributes() -> TargetAttributes {
+        TargetAttributes {
+            crate_name: "mock_crate".to_owned(),
+            crate_root: Some("src/root.rs".to_owned()),
+            ..TargetAttributes::default()
+        }
+    }
+
+    #[test]
+    fn render_rust_library() {
+        let mut context = Context::default();
+        let crate_id = CrateId::new("mock_crate".to_owned(), "0.1.0".to_owned());
+        context.crates.insert(
+            crate_id.clone(),
+            CrateContext {
+                name: crate_id.name,
+                version: crate_id.version,
+                targets: vec![Rule::Library(mock_target_attributes())],
+                ..CrateContext::default()
+            },
+        );
+
+        let renderer = Renderer::new(mock_render_config());
+        let output = renderer.render(&context).unwrap();
+
+        let build_file_content = output
+            .get(&PathBuf::from("BUILD.mock_crate-0.1.0.bazel"))
+            .unwrap();
+
+        assert!(build_file_content.contains("rust_library("));
+        assert!(build_file_content.contains("name = \"mock_crate\""));
+    }
+
+    #[test]
+    fn render_cargo_build_script() {
+        let mut context = Context::default();
+        let crate_id = CrateId::new("mock_crate".to_owned(), "0.1.0".to_owned());
+        context.crates.insert(
+            crate_id.clone(),
+            CrateContext {
+                name: crate_id.name,
+                version: crate_id.version,
+                targets: vec![Rule::BuildScript(TargetAttributes {
+                    crate_name: "build_script_build".to_owned(),
+                    crate_root: Some("build.rs".to_owned()),
+                    ..TargetAttributes::default()
+                })],
+                // Build script attributes are required.
+                build_script_attrs: Some(BuildScriptAttributes::default()),
+                ..CrateContext::default()
+            },
+        );
+
+        let renderer = Renderer::new(mock_render_config());
+        let output = renderer.render(&context).unwrap();
+
+        let build_file_content = output
+            .get(&PathBuf::from("BUILD.mock_crate-0.1.0.bazel"))
+            .unwrap();
+
+        assert!(build_file_content.contains("cargo_build_script("));
+        assert!(build_file_content.contains("name = \"build_script_build\""));
+
+        // Ensure `cargo_build_script` requirements are met
+        assert!(build_file_content.contains("name = \"mock_crate_build_script\""));
+    }
+
+    #[test]
+    fn render_proc_macro() {
+        let mut context = Context::default();
+        let crate_id = CrateId::new("mock_crate".to_owned(), "0.1.0".to_owned());
+        context.crates.insert(
+            crate_id.clone(),
+            CrateContext {
+                name: crate_id.name,
+                version: crate_id.version,
+                targets: vec![Rule::ProcMacro(mock_target_attributes())],
+                ..CrateContext::default()
+            },
+        );
+
+        let renderer = Renderer::new(mock_render_config());
+        let output = renderer.render(&context).unwrap();
+
+        let build_file_content = output
+            .get(&PathBuf::from("BUILD.mock_crate-0.1.0.bazel"))
+            .unwrap();
+
+        assert!(build_file_content.contains("rust_proc_macro("));
+        assert!(build_file_content.contains("name = \"mock_crate\""));
+    }
+
+    #[test]
+    fn render_binary() {
+        let mut context = Context::default();
+        let crate_id = CrateId::new("mock_crate".to_owned(), "0.1.0".to_owned());
+        context.crates.insert(
+            crate_id.clone(),
+            CrateContext {
+                name: crate_id.name,
+                version: crate_id.version,
+                targets: vec![Rule::Binary(mock_target_attributes())],
+                ..CrateContext::default()
+            },
+        );
+
+        let renderer = Renderer::new(mock_render_config());
+        let output = renderer.render(&context).unwrap();
+
+        let build_file_content = output
+            .get(&PathBuf::from("BUILD.mock_crate-0.1.0.bazel"))
+            .unwrap();
+
+        assert!(build_file_content.contains("rust_binary("));
+        assert!(build_file_content.contains("name = \"mock_crate__bin\""));
+    }
+
+    #[test]
+    fn render_additive_build_contents() {
+        let mut context = Context::default();
+        let crate_id = CrateId::new("mock_crate".to_owned(), "0.1.0".to_owned());
+        context.crates.insert(
+            crate_id.clone(),
+            CrateContext {
+                name: crate_id.name,
+                version: crate_id.version,
+                targets: vec![Rule::Binary(mock_target_attributes())],
+                additive_build_file_content: Some(
+                    "# Hello World from additive section!".to_owned(),
+                ),
+                ..CrateContext::default()
+            },
+        );
+
+        let renderer = Renderer::new(mock_render_config());
+        let output = renderer.render(&context).unwrap();
+
+        let build_file_content = output
+            .get(&PathBuf::from("BUILD.mock_crate-0.1.0.bazel"))
+            .unwrap();
+
+        assert!(build_file_content.contains("# Hello World from additive section!"));
+    }
+
+    #[test]
+    fn render_aliases() {
+        let annotations = Annotations::new(
+            test::metadata::alias(),
+            test::lockfile::alias(),
+            Config::default(),
+        )
+        .unwrap();
+        let context = Context::new(annotations).unwrap();
+
+        let renderer = Renderer::new(mock_render_config());
+        let output = renderer.render(&context).unwrap();
+
+        let build_file_content = output.get(&PathBuf::from("BUILD.bazel")).unwrap();
+
+        assert!(build_file_content.contains(r#"name = "names-0.12.1-dev__names","#));
+        assert!(build_file_content.contains(r#"name = "names-0.13.0__names","#));
+    }
+
+    #[test]
+    fn render_crate_repositories() {
+        let mut context = Context::default();
+        let crate_id = CrateId::new("mock_crate".to_owned(), "0.1.0".to_owned());
+        context.crates.insert(
+            crate_id.clone(),
+            CrateContext {
+                name: crate_id.name,
+                version: crate_id.version,
+                targets: vec![Rule::Library(mock_target_attributes())],
+                ..CrateContext::default()
+            },
+        );
+
+        let renderer = Renderer::new(mock_render_config());
+        let output = renderer.render(&context).unwrap();
+
+        let defs_module = output.get(&PathBuf::from("defs.bzl")).unwrap();
+
+        assert!(defs_module.contains("def crate_repositories():"));
+    }
+
+    #[test]
+    fn remote_remote_vendor_mode() {
+        let mut context = Context::default();
+        let crate_id = CrateId::new("mock_crate".to_owned(), "0.1.0".to_owned());
+        context.crates.insert(
+            crate_id.clone(),
+            CrateContext {
+                name: crate_id.name,
+                version: crate_id.version,
+                targets: vec![Rule::Library(mock_target_attributes())],
+                ..CrateContext::default()
+            },
+        );
+
+        // Enable remote vendor mode
+        let config = RenderConfig {
+            vendor_mode: Some(VendorMode::Remote),
+            ..mock_render_config()
+        };
+
+        let renderer = Renderer::new(config);
+        let output = renderer.render(&context).unwrap();
+
+        let defs_module = output.get(&PathBuf::from("defs.bzl")).unwrap();
+        assert!(defs_module.contains("def crate_repositories():"));
+
+        let crates_module = output.get(&PathBuf::from("crates.bzl")).unwrap();
+        assert!(crates_module.contains("def crate_repositories():"));
+    }
+
+    #[test]
+    fn remote_local_vendor_mode() {
+        let mut context = Context::default();
+        let crate_id = CrateId::new("mock_crate".to_owned(), "0.1.0".to_owned());
+        context.crates.insert(
+            crate_id.clone(),
+            CrateContext {
+                name: crate_id.name,
+                version: crate_id.version,
+                targets: vec![Rule::Library(mock_target_attributes())],
+                ..CrateContext::default()
+            },
+        );
+
+        // Enable local vendor mode
+        let config = RenderConfig {
+            vendor_mode: Some(VendorMode::Local),
+            ..mock_render_config()
+        };
+
+        let renderer = Renderer::new(config);
+        let output = renderer.render(&context).unwrap();
+
+        // Local vendoring does not produce a `crate_repositories` macro
+        let defs_module = output.get(&PathBuf::from("defs.bzl")).unwrap();
+        assert!(!defs_module.contains("def crate_repositories():"));
+
+        // Local vendoring does not produce a `crates.bzl` file.
+        assert!(output.get(&PathBuf::from("crates.bzl")).is_none());
+    }
+}
