diff --git a/example/assets/sample_data.json b/example/assets/sample_data.json
index 467bcadd..0e7f9e8d 100644
--- a/example/assets/sample_data.json
+++ b/example/assets/sample_data.json
@@ -536,5 +536,10 @@
   },
   {
     "insert": "\n"
+  },
+  {
+    "insert": {
+      "formula": "x=\\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}"
+    }
   }
-]
\ No newline at end of file
+]
diff --git a/lib/src/models/documents/nodes/embeddable.dart b/lib/src/models/documents/nodes/embeddable.dart
index 61d5e115..b2db0abc 100644
--- a/lib/src/models/documents/nodes/embeddable.dart
+++ b/lib/src/models/documents/nodes/embeddable.dart
@@ -38,6 +38,9 @@ class BlockEmbed extends Embeddable {
   static const String videoType = 'video';
   static BlockEmbed video(String videoUrl) => BlockEmbed(videoType, videoUrl);
 
+  static const String formulaType = 'formula';
+  static BlockEmbed formula(String formula) => BlockEmbed(formulaType, formula);
+
   static const String customType = 'custom';
   static BlockEmbed custom(CustomBlockEmbed customBlock) =>
       BlockEmbed(customType, customBlock.toJsonString());
diff --git a/lib/src/widgets/embeds/default_embed_builder.dart b/lib/src/widgets/embeds/default_embed_builder.dart
index 0eb22b5a..50f8f037 100644
--- a/lib/src/widgets/embeds/default_embed_builder.dart
+++ b/lib/src/widgets/embeds/default_embed_builder.dart
@@ -1,7 +1,9 @@
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
 import 'package:gallery_saver/gallery_saver.dart';
+import 'package:math_keyboard/math_keyboard.dart';
 import 'package:tuple/tuple.dart';
 
 import '../../models/documents/attribute.dart';
@@ -154,6 +156,24 @@ Widget defaultEmbedBuilder(
         readOnly: readOnly,
         onVideoInit: onVideoInit,
       );
+    case BlockEmbed.formulaType:
+      final mathController = MathFieldEditingController();
+
+      return Focus(
+        onFocusChange: (hasFocus) {
+          if (hasFocus) {
+            // If the MathField is tapped, hides the built in keyboard
+            SystemChannels.textInput.invokeMethod('TextInput.hide');
+            print(mathController.currentEditingValue());
+          }
+        },
+        child: MathField(
+          controller: mathController,
+          variables: const ['x', 'y', 'z'],
+          onChanged: (value) {},
+          onSubmitted: (value) {},
+        ),
+      );
     default:
       throw UnimplementedError(
         'Embeddable type "${node.value.type}" is not supported by default '
diff --git a/lib/src/widgets/toolbar.dart b/lib/src/widgets/toolbar.dart
index 198b6dff..40cffdf0 100644
--- a/lib/src/widgets/toolbar.dart
+++ b/lib/src/widgets/toolbar.dart
@@ -14,6 +14,7 @@ import 'toolbar/arrow_indicated_button_list.dart';
 import 'toolbar/camera_button.dart';
 import 'toolbar/clear_format_button.dart';
 import 'toolbar/color_button.dart';
+import 'toolbar/formula_button.dart';
 import 'toolbar/history_button.dart';
 import 'toolbar/image_button.dart';
 import 'toolbar/image_video_utils.dart';
@@ -109,6 +110,7 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
     bool multiRowsDisplay = true,
     bool showImageButton = true,
     bool showVideoButton = true,
+    bool showFormulaButton = false,
     bool showCameraButton = true,
     bool showDirection = false,
     bool showSearchButton = true,
@@ -364,6 +366,18 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget {
             webVideoPickImpl: webVideoPickImpl,
             iconTheme: iconTheme,
           ),
+        if (showFormulaButton)
+          FormulaButton(
+            icon: Icons.functions,
+            iconSize: toolbarIconSize,
+            controller: controller,
+            onImagePickCallback: onImagePickCallback,
+            filePickImpl: filePickImpl,
+            webImagePickImpl: webImagePickImpl,
+            mediaPickSettingSelector: mediaPickSettingSelector,
+            iconTheme: iconTheme,
+            dialogTheme: dialogTheme,
+          ),
         if (showDividers &&
             isButtonGroupShown[0] &&
             (isButtonGroupShown[1] ||
diff --git a/lib/src/widgets/toolbar/formula_button.dart b/lib/src/widgets/toolbar/formula_button.dart
new file mode 100644
index 00000000..7c7fc9b3
--- /dev/null
+++ b/lib/src/widgets/toolbar/formula_button.dart
@@ -0,0 +1,69 @@
+import 'package:flutter/material.dart';
+import 'package:image_picker/image_picker.dart';
+
+import '../../models/documents/nodes/embeddable.dart';
+import '../../models/themes/quill_dialog_theme.dart';
+import '../../models/themes/quill_icon_theme.dart';
+import '../controller.dart';
+import '../toolbar.dart';
+
+class FormulaButton extends StatelessWidget {
+  const FormulaButton({
+    required this.icon,
+    required this.controller,
+    this.iconSize = kDefaultIconSize,
+    this.onImagePickCallback,
+    this.fillColor,
+    this.filePickImpl,
+    this.webImagePickImpl,
+    this.mediaPickSettingSelector,
+    this.iconTheme,
+    this.dialogTheme,
+    Key? key,
+  }) : super(key: key);
+
+  final IconData icon;
+  final double iconSize;
+
+  final Color? fillColor;
+
+  final QuillController controller;
+
+  final OnImagePickCallback? onImagePickCallback;
+
+  final WebImagePickImpl? webImagePickImpl;
+
+  final FilePickImpl? filePickImpl;
+
+  final MediaPickSettingSelector? mediaPickSettingSelector;
+
+  final QuillIconTheme? iconTheme;
+
+  final QuillDialogTheme? dialogTheme;
+
+  @override
+  Widget build(BuildContext context) {
+    final theme = Theme.of(context);
+
+    final iconColor = iconTheme?.iconUnselectedColor ?? theme.iconTheme.color;
+    final iconFillColor =
+        iconTheme?.iconUnselectedFillColor ?? (fillColor ?? theme.canvasColor);
+
+    return QuillIconButton(
+      icon: Icon(icon, size: iconSize, color: iconColor),
+      highlightElevation: 0,
+      hoverElevation: 0,
+      size: iconSize * 1.77,
+      fillColor: iconFillColor,
+      borderRadius: iconTheme?.borderRadius ?? 2,
+      onPressed: () => _onPressedHandler(context),
+    );
+  }
+
+  Future<void> _onPressedHandler(BuildContext context) async {
+    final index = controller.selection.baseOffset;
+    final length = controller.selection.extentOffset - index;
+
+    controller.replaceText(index, length, BlockEmbed.formula(''), null);
+  }
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index e70dc559..e3fb5f21 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -30,6 +30,7 @@ dependencies:
   gallery_saver: ^2.3.2
   device_info_plus: ^4.0.0
   platform: ^3.1.0
+  math_keyboard: ^0.1.6
 
 dev_dependencies:
   flutter_test: