diff --git a/jsonnet/kube-prometheus/lib/mixin.libsonnet b/jsonnet/kube-prometheus/lib/mixin.libsonnet
new file mode 100644
index 0000000000000000000000000000000000000000..ae39425ddfa49fccfb7d6f95123e6ffe96f72ad6
--- /dev/null
+++ b/jsonnet/kube-prometheus/lib/mixin.libsonnet
@@ -0,0 +1,38 @@
+local defaults = {
+  name: error 'provide name',
+  namespace: 'monitoring',
+  labels: {
+    prometheus: 'k8s',
+  },
+  mixin: error 'provide a mixin',
+};
+
+function(params) {
+  config:: defaults + params,
+
+  local m = self,
+
+  local prometheusRules = if std.objectHasAll(m.config.mixin, 'prometheusRules') || std.objectHasAll(m.config.mixin, 'prometheusAlerts') then {
+    apiVersion: 'monitoring.coreos.com/v1',
+    kind: 'PrometheusRule',
+    metadata: {
+      labels: m.config.labels,
+      name: m.config.name,
+      namespace: m.config.namespace,
+    },
+    spec: {
+      local r = if std.objectHasAll(m.config.mixin, 'prometheusRules') then m.config.mixin.prometheusRules.groups else [],
+      local a = if std.objectHasAll(m.config.mixin, 'prometheusAlerts') then m.config.mixin.prometheusAlerts.groups else [],
+      groups: a + r,
+    },
+  },
+
+  local grafanaDashboards = if std.objectHasAll(m.config.mixin, 'grafanaDashboards') then (
+    if std.objectHas(m.config, 'dashboardFolder') then {
+      [m.config.dashboardFolder]+: m.config.mixin.grafanaDashboards,
+    } else (m.config.mixin.grafanaDashboards)
+  ),
+
+  prometheusRules: prometheusRules,
+  grafanaDashboards: grafanaDashboards,
+}