diff --git a/src/wuttaweb/grids/base.py b/src/wuttaweb/grids/base.py
index 33269f2..e93627f 100644
--- a/src/wuttaweb/grids/base.py
+++ b/src/wuttaweb/grids/base.py
@@ -118,6 +118,11 @@ class Grid:
        See also :meth:`set_renderer()` and
        :meth:`set_default_renderers()`.
 
+    .. attribute:: checkable
+
+       Boolean indicating whether the grid should expose per-row
+       checkboxes.
+
     .. attribute:: row_class
 
        This represents the CSS ``class`` attribute for a row within
@@ -362,6 +367,7 @@ class Grid:
             data=None,
             labels={},
             renderers={},
+            checkable=False,
             row_class=None,
             actions=[],
             linked_columns=[],
@@ -388,6 +394,7 @@ class Grid:
         self.key = key
         self.data = data
         self.labels = labels or {}
+        self.checkable = checkable
         self.row_class = row_class
         self.actions = actions or []
         self.linked_columns = linked_columns or []
diff --git a/src/wuttaweb/templates/grids/vue_template.mako b/src/wuttaweb/templates/grids/vue_template.mako
index ba548cb..fa7b8f7 100644
--- a/src/wuttaweb/templates/grids/vue_template.mako
+++ b/src/wuttaweb/templates/grids/vue_template.mako
@@ -116,6 +116,13 @@
                 hoverable
                 icon-pack="fas"
 
+                ## checkboxes
+                % if grid.checkable:
+                    checkable
+                    checkbox-position="right"
+                    :checked-rows.sync="checkedRows"
+                % endif
+
                 ## sorting
                 % if grid.sortable:
                     ## nb. buefy/oruga only support *one* default sorter
@@ -267,6 +274,11 @@
           shareLink: null,
       % endif
 
+      ## checkboxes
+      % if grid.checkable:
+          checkedRows: [],
+      % endif
+
       ## filtering
       % if grid.filterable:
           filters: ${json.dumps(grid.get_vue_filters())|n},
diff --git a/src/wuttaweb/views/master.py b/src/wuttaweb/views/master.py
index 61d4d14..5903fe4 100644
--- a/src/wuttaweb/views/master.py
+++ b/src/wuttaweb/views/master.py
@@ -189,6 +189,12 @@ class MasterView(View):
 
        This is optional; see also :meth:`get_grid_columns()`.
 
+    .. attribute:: checkable
+
+       Boolean indicating whether the grid should expose per-row
+       checkboxes.  This is passed along to set
+       :attr:`~wuttaweb.grids.base.Grid.checkable` on the grid.
+
     .. method:: grid_row_class(obj, data, i)
 
        This method is *not* defined on the ``MasterView`` base class;
@@ -395,6 +401,7 @@ class MasterView(View):
     # features
     listable = True
     has_grid = True
+    checkable = False
     filterable = True
     filter_defaults = None
     sortable = True
@@ -1992,6 +1999,7 @@ class MasterView(View):
 
             kwargs['tools'] = tools
 
+        kwargs.setdefault('checkable', self.checkable)
         if hasattr(self, 'grid_row_class'):
             kwargs.setdefault('row_class', self.grid_row_class)
         kwargs.setdefault('filterable', self.filterable)