diff --git a/pom.xml b/pom.xml
index f635ee0ac..73b897f6c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,6 +31,7 @@
providers/flagd
providers/flagsmith
providers/go-feature-flag
+ providers/jsonlogic-eval-provider
providers/env-var
diff --git a/providers/jsonlogic-eval-provider/README.md b/providers/jsonlogic-eval-provider/README.md
new file mode 100644
index 000000000..25b146c8b
--- /dev/null
+++ b/providers/jsonlogic-eval-provider/README.md
@@ -0,0 +1,41 @@
+# JSONLogic Evaluation Provider
+
+This provider does inline evaluation (e.g. no hot-path remote calls) based on [JSONLogic](https://jsonlogic.com/). This should allow you to
+achieve low latency flag evaluation.
+
+## Installation
+
+
+```xml
+
+
+ dev.openfeature.contrib.providers
+ jsonlogic-eval-provider
+ 0.0.1
+
+```
+
+
+## Usage
+
+You will need to create a custom class which implements the `RuleFetcher` interface. This code should cache your
+rules locally. During the `initialization` method, it should also set up a mechanism to stay up to date with remote
+flag changes. You can see `FileBasedFetcher` as a simplified example.
+
+```java
+JsonlogicProvider jlp = new JsonlogicProvider(new RuleFetcher() {
+ @Override
+ public void initialize(EvaluationContext initialContext) {
+ // setup initial fetch & stay-up-to-date logic
+ }
+
+ @Nullable
+ @Override
+ public String getRuleForKey(String key) {
+ // return the jsonlogic rule in string format for a given flag key
+ return null;
+ }
+})
+
+OpenFeature.setProvider(jlp);
+```
\ No newline at end of file
diff --git a/providers/jsonlogic-eval-provider/pom.xml b/providers/jsonlogic-eval-provider/pom.xml
new file mode 100644
index 000000000..ad5fce5ec
--- /dev/null
+++ b/providers/jsonlogic-eval-provider/pom.xml
@@ -0,0 +1,53 @@
+
+
+ 4.0.0
+
+ dev.openfeature.contrib
+ parent
+ 0.1.0
+ ../../pom.xml
+
+
+ dev.openfeature.contrib.providers
+ jsonlogic-eval-provider
+ 0.0.1
+
+ inline-evaluating-provider
+ Allows for evaluating rules on the client without synchronous calls to a backend
+ https://openfeature.dev
+
+
+
+ justinabrahms
+ Justin Abrahms
+ OpenFeature
+ https://openfeature.dev/
+
+
+
+
+
+ io.github.jamsesso
+ json-logic-java
+ 1.0.7
+
+
+ org.json
+ json
+ 20230227
+
+
+ com.github.spotbugs
+ spotbugs-annotations
+ 4.7.3
+ compile
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/providers/jsonlogic-eval-provider/src/main/java/dev/openfeature/contrib/providers/jsonlogic/FileBasedFetcher.java b/providers/jsonlogic-eval-provider/src/main/java/dev/openfeature/contrib/providers/jsonlogic/FileBasedFetcher.java
new file mode 100644
index 000000000..7def40764
--- /dev/null
+++ b/providers/jsonlogic-eval-provider/src/main/java/dev/openfeature/contrib/providers/jsonlogic/FileBasedFetcher.java
@@ -0,0 +1,48 @@
+package dev.openfeature.contrib.providers.jsonlogic;
+
+import dev.openfeature.sdk.EvaluationContext;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.logging.Logger;
+
+/**
+ * A {@link RuleFetcher} which reads in the rules from a file. It assumes that the keys are the flag keys and the
+ * values are the json logic rules.
+ */
+@SuppressFBWarnings(
+ value = "PATH_TRAVERSAL_IN",
+ justification = "This is expected to read files based on user input"
+)
+public class FileBasedFetcher implements RuleFetcher {
+ private static final Logger log = Logger.getLogger(String.valueOf(FileBasedFetcher.class));
+ private final JSONObject rules;
+
+ /**
+ * Create a file based fetcher give a file URI.
+ * @param filename URI to a given file.
+ * @throws IOException when we can't load the file correctly
+ */
+ public FileBasedFetcher(URI filename) throws IOException {
+ String jsonData = String.join("", Files.readAllLines(Paths.get(filename)));
+ rules = new JSONObject(jsonData);
+ }
+
+ @Override
+ public String getRuleForKey(String key) {
+ try {
+ return rules.getJSONObject(key).toString();
+ } catch (JSONException e) {
+ log.warning(String.format("Unable to deserialize rule for %s due to exception %s", key, e));
+ }
+ return null;
+ }
+
+ @Override public void initialize(EvaluationContext initialContext) {
+ }
+}
diff --git a/providers/jsonlogic-eval-provider/src/main/java/dev/openfeature/contrib/providers/jsonlogic/JsonlogicProvider.java b/providers/jsonlogic-eval-provider/src/main/java/dev/openfeature/contrib/providers/jsonlogic/JsonlogicProvider.java
new file mode 100644
index 000000000..8617ac691
--- /dev/null
+++ b/providers/jsonlogic-eval-provider/src/main/java/dev/openfeature/contrib/providers/jsonlogic/JsonlogicProvider.java
@@ -0,0 +1,87 @@
+package dev.openfeature.contrib.providers.jsonlogic;
+
+import dev.openfeature.sdk.*;
+import dev.openfeature.sdk.exceptions.ParseError;
+import io.github.jamsesso.jsonlogic.JsonLogic;
+import io.github.jamsesso.jsonlogic.JsonLogicException;
+
+import java.util.function.Function;
+
+/**
+ * A provider which evaluates JsonLogic rules provided by a {@link RuleFetcher}.
+ */
+public class JsonlogicProvider implements FeatureProvider {
+ private final JsonLogic logic;
+ private final RuleFetcher fetcher;
+
+
+ public void initialize(EvaluationContext initialContext) {
+ fetcher.initialize(initialContext);
+ }
+
+ public JsonlogicProvider(RuleFetcher fetcher) {
+ this.logic = new JsonLogic();
+ this.fetcher = fetcher;
+ }
+
+ public JsonlogicProvider(JsonLogic logic, RuleFetcher fetcher) {
+ this.logic = logic;
+ this.fetcher = fetcher;
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return () -> "JsonLogicProvider(" + this.fetcher.getClass().getName() + ")";
+ }
+
+ @Override
+ public ProviderEvaluation getBooleanEvaluation(String key, Boolean defaultValue, EvaluationContext ctx) {
+ return evalRuleForKey(key, defaultValue, ctx);
+ }
+
+ @Override
+ public ProviderEvaluation getStringEvaluation(String key, String defaultValue, EvaluationContext ctx) {
+ return evalRuleForKey(key, defaultValue, ctx);
+ }
+
+ @Override
+ public ProviderEvaluation getIntegerEvaluation(String key, Integer defaultValue, EvaluationContext ctx) {
+ // jsonlogic only returns doubles, not integers.
+ return evalRuleForKey(key, defaultValue, ctx, (o) -> ((Double) o).intValue());
+ }
+
+ @Override
+ public ProviderEvaluation getDoubleEvaluation(String key, Double defaultValue, EvaluationContext ctx) {
+ return evalRuleForKey(key, defaultValue, ctx);
+ }
+
+ @Override
+ public ProviderEvaluation getObjectEvaluation(String s, Value value, EvaluationContext evaluationContext) {
+ // we can't use the common implementation because we need to convert to-and-from Value objects.
+ throw new UnsupportedOperationException("Haven't gotten there yet.");
+ }
+
+ private ProviderEvaluation evalRuleForKey(String key, T defaultValue, EvaluationContext ctx) {
+ return evalRuleForKey(key, defaultValue, ctx, (o) -> (T) o);
+ }
+
+ private ProviderEvaluation evalRuleForKey(
+ String key, T defaultValue, EvaluationContext ctx, Function