diff --git a/web/components/label.css b/web/components/label.css
new file mode 100644
--- /dev/null
+++ b/web/components/label.css
@@ -0,0 +1,5 @@
+div.label {
+  line-height: 1.5;
+  padding: 4px 8px;
+  border-radius: 8px;
+}
diff --git a/web/components/label.react.js b/web/components/label.react.js
new file mode 100644
--- /dev/null
+++ b/web/components/label.react.js
@@ -0,0 +1,38 @@
+// @flow
+
+import * as React from 'react';
+
+import css from './label.css';
+
+type Props = {
+  +size?: string | number,
+  +color?: string,
+  +bg?: string,
+  +children: React.Node,
+};
+
+function Label(props: Props): React.Node {
+  const {
+    size = '12px',
+    color = 'var(--label-default-color)',
+    bg = 'var(--label-default-bg)',
+    children,
+  } = props;
+
+  const labelStyle = React.useMemo(
+    () => ({
+      fontSize: size,
+      color: color,
+      background: bg,
+    }),
+    [bg, color, size],
+  );
+
+  return (
+    <div style={labelStyle} className={css.label}>
+      {children}
+    </div>
+  );
+}
+
+export default Label;
diff --git a/web/theme.css b/web/theme.css
--- a/web/theme.css
+++ b/web/theme.css
@@ -132,4 +132,6 @@
   --tabs-header-background-border: var(--shades-black-80);
   --tabs-header-background-color-hover: var(--shades-white-80);
   --tabs-header-background-border-hover: var(--shades-black-70);
+  --label-default-bg: var(--violet-dark-80);
+  --label-default-color: var(--shades-white-80);
 }