diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/LootEntryTypeRegistry.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/LootEntryTypeRegistry.java
index 251e2bab6..197579113 100644
--- a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/LootEntryTypeRegistry.java
+++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/api/registry/LootEntryTypeRegistry.java
@@ -20,18 +20,13 @@ import net.fabricmc.fabric.impl.registry.LootEntryTypeRegistryImpl;
 import net.minecraft.world.loot.entry.LootEntry;
 
 /**
- * Fabric's extensions to {@code net.minecraft.world.loot.entry.LootEntries} for registering
- * custom loot entry types.
- *
- * @see #register
+ * @deprecated Use {@link net.fabricmc.fabric.api.loot.v1.LootEntryTypeRegistry}
  */
+@Deprecated
 public interface LootEntryTypeRegistry {
+	@Deprecated
 	final LootEntryTypeRegistry INSTANCE = LootEntryTypeRegistryImpl.INSTANCE;
 
-	/**
-	 * Registers a loot entry type by its serializer.
-	 *
-	 * @param serializer the loot entry serializer
-	 */
+	@Deprecated
 	void register(LootEntry.Serializer<?> serializer);
 }
diff --git a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/impl/registry/LootEntryTypeRegistryImpl.java b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/impl/registry/LootEntryTypeRegistryImpl.java
index c07cad5c2..9182cf50e 100644
--- a/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/impl/registry/LootEntryTypeRegistryImpl.java
+++ b/fabric-content-registries-v0/src/main/java/net/fabricmc/fabric/impl/registry/LootEntryTypeRegistryImpl.java
@@ -21,10 +21,9 @@ import net.minecraft.world.loot.entry.LootEntries;
 import net.minecraft.world.loot.entry.LootEntry;
 
 import java.lang.reflect.Method;
-import java.util.function.Consumer;
 
+@Deprecated
 public final class LootEntryTypeRegistryImpl implements LootEntryTypeRegistry {
-	private static Consumer<LootEntry.Serializer<?>> registerFunction;
 	public static final LootEntryTypeRegistryImpl INSTANCE = new LootEntryTypeRegistryImpl();
 	private static final Method REGISTER_METHOD;
 
diff --git a/fabric-loot-tables-v1/build.gradle b/fabric-loot-tables-v1/build.gradle
new file mode 100644
index 000000000..1b3ee6646
--- /dev/null
+++ b/fabric-loot-tables-v1/build.gradle
@@ -0,0 +1,6 @@
+archivesBaseName = "fabric-loot-tables-v1"
+version = "0.1.0"
+
+dependencies {
+	compile project(path: ':fabric-api-base', configuration: 'dev')
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/FabricLootPool.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/FabricLootPool.java
new file mode 100644
index 000000000..5ce08cf96
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/FabricLootPool.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016, 2017, 2018 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.api.loot.v1;
+
+import net.minecraft.world.loot.LootPool;
+import net.minecraft.world.loot.LootTableRange;
+import net.minecraft.world.loot.condition.LootCondition;
+import net.minecraft.world.loot.entry.LootEntry;
+import net.minecraft.world.loot.function.LootFunction;
+
+import java.util.List;
+
+/**
+ * An interface implemented by all {@code net.minecraft.world.loot.LootPool} instances when
+ * Fabric API is present. Contains accessors for various fields.
+ */
+public interface FabricLootPool {
+	default LootPool asVanilla() {
+		return (LootPool) this;
+	}
+	List<LootEntry> getEntries();
+	List<LootCondition> getConditions();
+	List<LootFunction> getFunctions();
+	LootTableRange getRollsRange();
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/FabricLootPoolBuilder.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/FabricLootPoolBuilder.java
new file mode 100644
index 000000000..b694563b6
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/FabricLootPoolBuilder.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016, 2017, 2018 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.api.loot.v1;
+
+import net.fabricmc.fabric.mixin.loot.LootPoolBuilderHooks;
+import net.minecraft.world.loot.LootPool;
+import net.minecraft.world.loot.LootTableRange;
+import net.minecraft.world.loot.condition.LootCondition;
+import net.minecraft.world.loot.entry.LootEntry;
+import net.minecraft.world.loot.function.LootFunction;
+
+public class FabricLootPoolBuilder extends LootPool.Builder {
+	private final LootPoolBuilderHooks extended = (LootPoolBuilderHooks) this;
+
+	private FabricLootPoolBuilder() {}
+
+	private FabricLootPoolBuilder(LootPool pool) {
+		copyFrom(pool, true);
+	}
+
+	@Override
+	public FabricLootPoolBuilder withRolls(LootTableRange range) {
+		super.withRolls(range);
+		return this;
+	}
+
+	@Override
+	public FabricLootPoolBuilder withEntry(LootEntry.Builder<?> entry) {
+		super.withEntry(entry);
+		return this;
+	}
+
+	@Override
+	public FabricLootPoolBuilder withCondition(LootCondition.Builder condition) {
+		super.method_356(condition);
+		return this;
+	}
+
+	@Override
+	public FabricLootPoolBuilder withFunction(LootFunction.Builder function) {
+		super.method_353(function);
+		return this;
+	}
+
+	public FabricLootPoolBuilder withEntry(LootEntry entry) {
+		extended.getEntries().add(entry);
+		return this;
+	}
+
+	public FabricLootPoolBuilder withCondition(LootCondition condition) {
+		extended.getConditions().add(condition);
+		return this;
+	}
+
+	public FabricLootPoolBuilder withFunction(LootFunction function) {
+		extended.getFunctions().add(function);
+		return this;
+	}
+
+	/**
+	 * Copies the entries, conditions and functions of the {@code pool} to this
+	 * builder.
+	 *
+	 * This is equal to {@code copyFrom(pool, false)}.
+	 */
+	public FabricLootPoolBuilder copyFrom(LootPool pool) {
+		return copyFrom(pool, false);
+	}
+
+	/**
+	 * Copies the entries, conditions and functions of the {@code pool} to this
+	 * builder.
+	 *
+	 * If {@code copyRolls} is true, the {@link FabricLootPool#getRollsRange rolls} of the pool are also copied.
+	 */
+	public FabricLootPoolBuilder copyFrom(LootPool pool, boolean copyRolls) {
+		FabricLootPool extendedPool = (FabricLootPool) pool;
+		extended.getConditions().addAll(extendedPool.getConditions());
+		extended.getFunctions().addAll(extendedPool.getFunctions());
+		extended.getEntries().addAll(extendedPool.getEntries());
+
+		if (copyRolls) {
+			withRolls(extendedPool.getRollsRange());
+		}
+
+		return this;
+	}
+
+	public static FabricLootPoolBuilder builder() {
+		return new FabricLootPoolBuilder();
+	}
+
+	public static FabricLootPoolBuilder of(LootPool pool) {
+		return new FabricLootPoolBuilder(pool);
+	}
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/FabricLootSupplier.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/FabricLootSupplier.java
new file mode 100644
index 000000000..cf2e56106
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/FabricLootSupplier.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, 2017, 2018 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.api.loot.v1;
+
+import net.minecraft.world.loot.LootPool;
+import net.minecraft.world.loot.LootSupplier;
+import net.minecraft.world.loot.context.LootContextType;
+import net.minecraft.world.loot.function.LootFunction;
+
+import java.util.List;
+
+/**
+ * An interface implemented by all {@code net.minecraft.world.loot.LootSupplier} instances when
+ * Fabric API is present. Contains accessors for various fields.
+ */
+public interface FabricLootSupplier {
+	default LootSupplier asVanilla() {
+		return (LootSupplier) this;
+	}
+	List<LootPool> getPools();
+	List<LootFunction> getFunctions();
+	LootContextType getType();
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/FabricLootSupplierBuilder.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/FabricLootSupplierBuilder.java
new file mode 100644
index 000000000..0174436b6
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/FabricLootSupplierBuilder.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2016, 2017, 2018 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.api.loot.v1;
+
+import net.fabricmc.fabric.mixin.loot.LootSupplierBuilderHooks;
+import net.minecraft.world.loot.LootPool;
+import net.minecraft.world.loot.LootSupplier;
+import net.minecraft.world.loot.context.LootContextType;
+import net.minecraft.world.loot.function.LootFunction;
+
+import java.util.Collection;
+
+public class FabricLootSupplierBuilder extends LootSupplier.Builder {
+	private final LootSupplierBuilderHooks extended = (LootSupplierBuilderHooks) this;
+
+	protected FabricLootSupplierBuilder() {}
+
+	private FabricLootSupplierBuilder(LootSupplier supplier) {
+		copyFrom(supplier, true);
+	}
+
+	@Override
+	public FabricLootSupplierBuilder withPool(LootPool.Builder pool) {
+		super.withPool(pool);
+		return this;
+	}
+
+	@Override
+	public FabricLootSupplierBuilder withType(LootContextType type) {
+		super.withType(type);
+		return this;
+	}
+
+	@Override
+	public FabricLootSupplierBuilder withFunction(LootFunction.Builder function) {
+		super.method_335(function);
+		return this;
+	}
+
+	public FabricLootSupplierBuilder withPool(LootPool pool) {
+		extended.getPools().add(pool);
+		return this;
+	}
+
+	public FabricLootSupplierBuilder withFunction(LootFunction function) {
+		extended.getFunctions().add(function);
+		return this;
+	}
+
+	public FabricLootSupplierBuilder withPools(Collection<LootPool> pools) {
+		pools.forEach(this::withPool);
+		return this;
+	}
+
+	public FabricLootSupplierBuilder withFunctions(Collection<LootFunction> functions) {
+		functions.forEach(this::withFunction);
+		return this;
+	}
+
+	/**
+	 * Copies the pools and functions of the {@code supplier} to this builder.
+	 * This is equal to {@code copyFrom(supplier, false)}.
+	 */
+	public FabricLootSupplierBuilder copyFrom(LootSupplier supplier) {
+		return copyFrom(supplier, false);
+	}
+
+	/**
+	 * Copies the pools and functions of the {@code supplier} to this builder.
+	 * If {@code copyType} is true, the {@link FabricLootSupplier#getType type} of the supplier is also copied.
+	 */
+	public FabricLootSupplierBuilder copyFrom(LootSupplier supplier, boolean copyType) {
+		FabricLootSupplier extendedSupplier = (FabricLootSupplier) supplier;
+		extended.getPools().addAll(extendedSupplier.getPools());
+		extended.getFunctions().addAll(extendedSupplier.getFunctions());
+
+		if (copyType) {
+			withType(extendedSupplier.getType());
+		}
+
+		return this;
+	}
+
+	public static FabricLootSupplierBuilder builder() {
+		return new FabricLootSupplierBuilder();
+	}
+
+	public static FabricLootSupplierBuilder of(LootSupplier supplier) {
+		return new FabricLootSupplierBuilder(supplier);
+	}
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/LootEntryTypeRegistry.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/LootEntryTypeRegistry.java
new file mode 100644
index 000000000..fa7fbea1c
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/LootEntryTypeRegistry.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.api.loot.v1;
+
+import net.fabricmc.fabric.impl.loot.LootEntryTypeRegistryImpl;
+import net.minecraft.world.loot.entry.LootEntry;
+
+/**
+ * Fabric's extensions to {@code net.minecraft.world.loot.entry.LootEntries} for registering
+ * custom loot entry types.
+ *
+ * @see #register
+ */
+public interface LootEntryTypeRegistry {
+	final LootEntryTypeRegistry INSTANCE = LootEntryTypeRegistryImpl.INSTANCE;
+
+	/**
+	 * Registers a loot entry type by its serializer.
+	 *
+	 * @param serializer the loot entry serializer
+	 */
+	void register(LootEntry.Serializer<?> serializer);
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/LootJsonParser.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/LootJsonParser.java
new file mode 100644
index 000000000..58df54867
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/LootJsonParser.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2016, 2017, 2018 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.api.loot.v1;
+
+import com.google.gson.Gson;
+import net.minecraft.resource.Resource;
+import net.minecraft.resource.ResourceManager;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.JsonHelper;
+import net.minecraft.util.Lazy;
+import net.minecraft.world.loot.*;
+import net.minecraft.world.loot.condition.LootCondition;
+import net.minecraft.world.loot.entry.LootEntry;
+import net.minecraft.world.loot.function.LootFunction;
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.reflect.Field;
+import java.nio.charset.StandardCharsets;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+public final class LootJsonParser {
+	/* Reading this from LootManager to access all serializers from vanilla. */
+	private static final Lazy<Gson> GSON = new Lazy<>(() -> {
+		try {
+			Field gsonField = Stream.of(LootManager.class.getDeclaredFields())
+					.filter(field -> field.getType() == Gson.class)
+					.findFirst()
+					.orElseThrow(() -> new RuntimeException("Gson not found in LootManager!"));
+			gsonField.setAccessible(true);
+			return (Gson) gsonField.get(null);
+		} catch (Exception e) {
+			throw new RuntimeException("Exception while getting Gson instance from LootManager", e);
+		}
+	});
+
+	private LootJsonParser() {
+
+	}
+
+	public static <T> T read(Reader json, Class<T> c) {
+		return JsonHelper.deserialize(GSON.get(), json, c);
+	}
+
+	public static <T> T read(String json, Class<T> c) {
+		return JsonHelper.deserialize(GSON.get(), json, c);
+	}
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/event/LootTableLoadingCallback.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/event/LootTableLoadingCallback.java
new file mode 100644
index 000000000..f59018088
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/api/loot/v1/event/LootTableLoadingCallback.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016, 2017, 2018 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.api.loot.v1.event;
+
+import net.fabricmc.fabric.api.event.Event;
+import net.fabricmc.fabric.api.event.EventFactory;
+import net.fabricmc.fabric.api.loot.v1.FabricLootSupplierBuilder;
+import net.minecraft.resource.ResourceManager;
+import net.minecraft.util.Identifier;
+import net.minecraft.world.loot.LootManager;
+import net.minecraft.world.loot.LootSupplier;
+
+/**
+ * An event handler that is called when loot tables are loaded.
+ * Use {@link #EVENT} to register instances.
+ */
+@FunctionalInterface
+public interface LootTableLoadingCallback {
+	@FunctionalInterface
+	interface LootTableSetter {
+		void set(LootSupplier supplier);
+	}
+
+	final Event<LootTableLoadingCallback> EVENT = EventFactory.createArrayBacked(
+			LootTableLoadingCallback.class,
+			(listeners) -> (resourceManager, manager, id, supplier, setter) -> {
+				for (LootTableLoadingCallback callback : listeners) {
+					callback.onLootTableLoading(resourceManager, manager, id, supplier, setter);
+				}
+			}
+	);
+
+	void onLootTableLoading(ResourceManager resourceManager, LootManager manager, Identifier id, FabricLootSupplierBuilder supplier, LootTableSetter setter);
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/impl/loot/LootEntryTypeRegistryImpl.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/impl/loot/LootEntryTypeRegistryImpl.java
new file mode 100644
index 000000000..194c9a8a4
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/impl/loot/LootEntryTypeRegistryImpl.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, 2017, 2018, 2019 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.impl.loot;
+
+import net.minecraft.world.loot.entry.LootEntries;
+import net.minecraft.world.loot.entry.LootEntry;
+
+import java.lang.reflect.Method;
+
+public final class LootEntryTypeRegistryImpl implements net.fabricmc.fabric.api.loot.v1.LootEntryTypeRegistry {
+	public static final LootEntryTypeRegistryImpl INSTANCE = new LootEntryTypeRegistryImpl();
+	private static final Method REGISTER_METHOD;
+
+	static {
+		Method target = null;
+		for (Method m : LootEntries.class.getDeclaredMethods()) {
+			if (m.getParameterCount() == 1 && m.getParameterTypes()[0] == LootEntry.Serializer.class) {
+				if (target != null) {
+					throw new RuntimeException("More than one register-like method found in LootEntries!");
+				} else {
+					target = m;
+				}
+			}
+		}
+
+		if (target == null) {
+			throw new RuntimeException("Could not find register-like method in LootEntries!");
+		} else {
+			REGISTER_METHOD = target;
+			REGISTER_METHOD.setAccessible(true);
+		}
+	}
+
+	private LootEntryTypeRegistryImpl() {
+	}
+
+	@Override
+	public void register(LootEntry.Serializer<?> serializer) {
+		try {
+			REGISTER_METHOD.invoke(null, serializer);
+		} catch (Throwable t) {
+			throw new RuntimeException(t);
+		}
+	}
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolBuilderHooks.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolBuilderHooks.java
new file mode 100644
index 000000000..f1bddb8ad
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/LootPoolBuilderHooks.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, 2017, 2018 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.mixin.loot;
+
+import net.minecraft.world.loot.LootPool;
+import net.minecraft.world.loot.condition.LootCondition;
+import net.minecraft.world.loot.entry.LootEntry;
+import net.minecraft.world.loot.function.LootFunction;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import java.util.List;
+
+@Mixin(LootPool.Builder.class)
+public interface LootPoolBuilderHooks {
+	@Accessor
+	List<LootEntry> getEntries();
+	@Accessor
+	List<LootCondition> getConditions();
+	@Accessor
+	List<LootFunction> getFunctions();
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/LootSupplierBuilderHooks.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/LootSupplierBuilderHooks.java
new file mode 100644
index 000000000..05f7f5836
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/LootSupplierBuilderHooks.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, 2017, 2018 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.mixin.loot;
+
+import net.minecraft.world.loot.LootPool;
+import net.minecraft.world.loot.LootSupplier;
+import net.minecraft.world.loot.function.LootFunction;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import java.util.List;
+
+@Mixin(LootSupplier.Builder.class)
+public interface LootSupplierBuilderHooks {
+	@Accessor
+	List<LootPool> getPools();
+	@Accessor
+	List<LootFunction> getFunctions();
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootManager.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootManager.java
new file mode 100644
index 000000000..4187ecc35
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootManager.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, 2017, 2018 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.mixin.loot;
+
+import net.fabricmc.fabric.api.loot.v1.event.LootTableLoadingCallback;
+import net.fabricmc.fabric.api.loot.v1.FabricLootSupplierBuilder;
+import net.minecraft.resource.ResourceManager;
+import net.minecraft.util.Identifier;
+import net.minecraft.world.loot.LootManager;
+import net.minecraft.world.loot.LootSupplier;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Mixin(LootManager.class)
+public class MixinLootManager {
+	@Shadow @Final private Map<Identifier, LootSupplier> suppliers;
+
+	@Inject(method = "apply", at = @At("RETURN"))
+	private void apply(ResourceManager manager, CallbackInfo info) {
+		Map<Identifier, LootSupplier> newSuppliers = new HashMap<>();
+
+		suppliers.forEach((id, supplier) -> {
+			FabricLootSupplierBuilder builder = FabricLootSupplierBuilder.of(supplier);
+
+			//noinspection ConstantConditions
+			LootTableLoadingCallback.EVENT.invoker().onLootTableLoading(
+				manager, (LootManager) (Object) this, id, builder, (s) -> newSuppliers.put(id, s)
+			);
+
+			newSuppliers.computeIfAbsent(id, (i) -> builder.create());
+		});
+
+		for (Identifier id : newSuppliers.keySet()) {
+			suppliers.put(id, newSuppliers.get(id));
+		}
+	}
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootPool.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootPool.java
new file mode 100644
index 000000000..c9ff1cd01
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootPool.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, 2017, 2018 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.mixin.loot;
+
+import net.fabricmc.fabric.api.loot.v1.FabricLootPool;
+import net.minecraft.world.loot.LootPool;
+import net.minecraft.world.loot.LootTableRange;
+import net.minecraft.world.loot.condition.LootCondition;
+import net.minecraft.world.loot.entry.LootEntry;
+import net.minecraft.world.loot.function.LootFunction;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import java.util.Arrays;
+import java.util.List;
+
+@Mixin(LootPool.class)
+public abstract class MixinLootPool implements FabricLootPool {
+	@Shadow @Final private LootEntry[] entries;
+
+	@Shadow @Final private LootCondition[] conditions;
+
+	@Shadow @Final private LootFunction[] functions;
+
+	@Override
+	public List<LootEntry> getEntries() {
+		return Arrays.asList(entries);
+	}
+
+	@Override
+	public List<LootCondition> getConditions() {
+		return Arrays.asList(conditions);
+	}
+
+	@Override
+	public List<LootFunction> getFunctions() {
+		return Arrays.asList(functions);
+	}
+
+	@Accessor
+	@Override
+	public abstract LootTableRange getRollsRange();
+}
diff --git a/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootSupplier.java b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootSupplier.java
new file mode 100644
index 000000000..a5c63152d
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/java/net/fabricmc/fabric/mixin/loot/MixinLootSupplier.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, 2017, 2018 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.mixin.loot;
+
+import net.fabricmc.fabric.api.loot.v1.FabricLootSupplier;
+import net.minecraft.world.loot.LootPool;
+import net.minecraft.world.loot.LootSupplier;
+import net.minecraft.world.loot.context.LootContextType;
+import net.minecraft.world.loot.function.LootFunction;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import java.util.Arrays;
+import java.util.List;
+
+@Mixin(LootSupplier.class)
+public abstract class MixinLootSupplier implements FabricLootSupplier {
+	@Shadow @Final private LootPool[] pools;
+	@Shadow @Final private LootFunction[] functions;
+
+	@Override
+	public List<LootPool> getPools() {
+		return Arrays.asList(pools);
+	}
+
+	@Override
+	public List<LootFunction> getFunctions() {
+		return Arrays.asList(functions);
+	}
+
+	@Accessor
+	@Override
+	public abstract LootContextType getType();
+}
diff --git a/fabric-loot-tables-v1/src/main/resources/fabric-loot-tables-v1.mixins.json b/fabric-loot-tables-v1/src/main/resources/fabric-loot-tables-v1.mixins.json
new file mode 100644
index 000000000..0d120730d
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/resources/fabric-loot-tables-v1.mixins.json
@@ -0,0 +1,15 @@
+{
+  "required": true,
+  "package": "net.fabricmc.fabric.mixin.loot",
+  "compatibilityLevel": "JAVA_8",
+  "mixins": [
+    "LootPoolBuilderHooks",
+    "LootSupplierBuilderHooks",
+    "MixinLootManager",
+    "MixinLootPool",
+    "MixinLootSupplier"
+  ],
+  "injectors": {
+    "defaultRequire": 1
+  }
+}
diff --git a/fabric-loot-tables-v1/src/main/resources/fabric.mod.json b/fabric-loot-tables-v1/src/main/resources/fabric.mod.json
new file mode 100644
index 000000000..6aa0d2d58
--- /dev/null
+++ b/fabric-loot-tables-v1/src/main/resources/fabric.mod.json
@@ -0,0 +1,13 @@
+{
+  "schemaVersion": 1,
+  "id": "fabric-loot-tables-v1",
+  "version": "${version}",
+  "license": "Apache-2.0",
+  "depends": {
+    "fabricloader": ">=0.4.0",
+    "fabric-api-base": "*"
+  },
+  "mixins": [
+    "fabric-loot-tables-v1.mixins.json"
+  ]
+}
diff --git a/fabric-testmods/java/net/fabricmc/fabric/loot/LootTableMod.java b/fabric-testmods/java/net/fabricmc/fabric/loot/LootTableMod.java
new file mode 100644
index 000000000..9646c059d
--- /dev/null
+++ b/fabric-testmods/java/net/fabricmc/fabric/loot/LootTableMod.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, 2017, 2018 FabricMC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.fabricmc.fabric.loot;
+
+import net.fabricmc.api.ModInitializer;
+import net.fabricmc.fabric.api.event.loot.LootTableLoadingCallback;
+import net.fabricmc.fabric.api.loot.FabricLootPoolBuilder;
+import net.fabricmc.fabric.api.loot.LootUtilities;
+import net.minecraft.item.Items;
+import net.minecraft.world.loot.ConstantLootTableRange;
+import net.minecraft.world.loot.LootPool;
+import net.minecraft.world.loot.condition.SurvivesExplosionLootCondition;
+import net.minecraft.world.loot.entry.ItemEntry;
+import net.minecraft.world.loot.entry.LootEntry;
+
+public class LootTableMod implements ModInitializer {
+	private static final String LOOT_ENTRY_JSON = "{\"type\":\"minecraft:item\",\"name\":\"minecraft:apple\"}";
+
+	@Override
+	public void onInitialize() {
+		LootTableLoadingCallback.EVENT.register((manager, id, supplier) -> {
+			if ("minecraft:blocks/dirt".equals(id.toString())) {
+				LootEntry entryFromString = LootUtilities.readEntryFromJson(LOOT_ENTRY_JSON);
+
+				LootPool pool = FabricLootPoolBuilder.builder()
+						.withEntry(ItemEntry.builder(Items.FEATHER))
+						.withEntry(entryFromString)
+						.withRolls(ConstantLootTableRange.create(1))
+						.withCondition(SurvivesExplosionLootCondition.method_871())
+						.build();
+
+				supplier.withPool(pool);
+			}
+		});
+	}
+}
diff --git a/settings.gradle b/settings.gradle
index 7e79bd499..32bda252f 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -22,6 +22,7 @@ include 'fabric-events-interaction-v0'
 include 'fabric-events-lifecycle-v0'
 include 'fabric-item-groups-v0'
 include 'fabric-keybindings-v0'
+include 'fabric-loot-tables-v1'
 include 'fabric-mining-levels-v0'
 include 'fabric-models-v0'
 include 'fabric-networking-v0'