diff --git a/src/tint/tint_lldb.py b/src/tint/tint_lldb.py
new file mode 100644
index 0000000..85a93ff
--- /dev/null
+++ b/src/tint/tint_lldb.py
@@ -0,0 +1,397 @@
+# Copyright 2022 The Tint Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Pretty printers for the Tint project.
+#
+# If using lldb from command line, add a line to your ~/.lldbinit to import the printers:
+#
+#    command script import /path/to/dawn/src/tint/tint_lldb.py
+#
+#
+# If using VS Code on MacOS with the Microsoft C/C++ extension, add the following to
+# your launch.json (make sure you specify an absolute path to tint_lldb.py):
+#
+#    "name": "Launch",
+#    "type": "cppdbg",
+#    "request": "launch",
+#    ...
+#    "setupCommands": [
+#        {
+#            "description": "Load tint pretty printers",
+#            "ignoreFailures": false,
+#            "text": "command script import /path/to/dawn/src/tint/tint_lldb.py,
+#        }
+#    ]
+#
+# If using VS Code with the CodeLLDB extension (https://github.com/vadimcn/vscode-lldb),
+# add the following to your launch.json:
+#
+#    "name": "Launch",
+#    "type": "lldb",
+#    "request": "launch",
+#    ...
+#    "initCommands": [
+#        "command script import /path/to/dawn/src/tint/tint_lldb.py"
+#    ]
+
+# Based on pretty printers for:
+# Rust: https://github.com/vadimcn/vscode-lldb/blob/master/formatters/rust.py
+# Dlang: https://github.com/Pure-D/dlang-debug/blob/master/lldb_dlang.py
+#
+#
+# Tips for debugging using VS Code:
+#
+# - Set a breakpoint where you can view the types you want to debug/write pretty printers for.
+# - Debug Console: -exec command script import /path/to/dawn/src/tint/tint_lldb.py
+# - You can re-run the above command to reload the printers after modifying the python script.
+
+# - Useful docs:
+#   Formattesr: https://lldb.llvm.org/use/variable.html
+#   Python API: https://lldb.llvm.org/python_api.html
+#   Especially:
+#     SBType: https://lldb.llvm.org/python_api/lldb.SBType.html
+#     SBValue: https://lldb.llvm.org/python_api/lldb.SBValue.html
+
+from __future__ import print_function, division
+import sys
+import logging
+import re
+import lldb
+import types
+
+if sys.version_info[0] == 2:
+    # python2-based LLDB accepts utf8-encoded ascii strings only.
+    def to_lldb_str(s): return s.encode(
+        'utf8', 'backslashreplace') if isinstance(s, unicode) else s
+    range = xrange
+else:
+    to_lldb_str = str
+
+string_encoding = "escape"  # remove | unicode | escape
+
+log = logging.getLogger(__name__)
+
+module = sys.modules[__name__]
+tint_category = None
+
+
+def __lldb_init_module(debugger, dict):
+    global tint_category
+
+    tint_category = debugger.CreateCategory('tint')
+    tint_category.SetEnabled(True)
+
+    attach_synthetic_to_type(
+        UtilsSlicePrinter, r'^tint::utils::Slice<.+>$', True)
+
+    attach_synthetic_to_type(
+        UtilsVectorPrinter, r'^tint::utils::Vector<.+>$', True)
+
+    attach_synthetic_to_type(
+        UtilsVectorRefPrinter, r'^tint::utils::VectorRef<.+>$', True)
+
+    attach_synthetic_to_type(
+        UtilsHashsetPrinter, r'^tint::utils::Hashset<.+>$', True)
+
+    attach_synthetic_to_type(
+        UtilsHashmapPrinter, r'^tint::utils::Hashmap<.+>$', True)
+
+
+def attach_synthetic_to_type(synth_class, type_name, is_regex=False):
+    global module, tint_category
+    synth = lldb.SBTypeSynthetic.CreateWithClassName(
+        __name__ + '.' + synth_class.__name__)
+    synth.SetOptions(lldb.eTypeOptionCascade)
+    ret = tint_category.AddTypeSynthetic(
+        lldb.SBTypeNameSpecifier(type_name, is_regex), synth)
+    log.debug('attaching synthetic %s to "%s", is_regex=%s -> %s',
+              synth_class.__name__, type_name, is_regex, ret)
+
+    def summary_fn(valobj, dict): return get_synth_summary(
+        synth_class, valobj, dict)
+    # LLDB accesses summary fn's by name, so we need to create a unique one.
+    summary_fn.__name__ = '_get_synth_summary_' + synth_class.__name__
+    setattr(module, summary_fn.__name__, summary_fn)
+    attach_summary_to_type(summary_fn, type_name, is_regex)
+
+
+def attach_summary_to_type(summary_fn, type_name, is_regex=False):
+    global module, tint_category
+    summary = lldb.SBTypeSummary.CreateWithFunctionName(
+        __name__ + '.' + summary_fn.__name__)
+    summary.SetOptions(lldb.eTypeOptionCascade)
+    ret = tint_category.AddTypeSummary(
+        lldb.SBTypeNameSpecifier(type_name, is_regex), summary)
+    log.debug('attaching summary %s to "%s", is_regex=%s -> %s',
+              summary_fn.__name__, type_name, is_regex, ret)
+
+
+def get_synth_summary(synth_class, valobj, dict):
+    ''''
+    get_summary' is annoyingly not a part of the standard LLDB synth provider API.
+    This trick allows us to share data extraction logic between synth providers and their sibling summary providers.
+    '''
+    synth = synth_class(valobj.GetNonSyntheticValue(), dict)
+    synth.update()
+    summary = synth.get_summary()
+    return to_lldb_str(summary)
+
+
+def member(valobj, *chain):
+    '''Performs chained GetChildMemberWithName lookups'''
+    for name in chain:
+        valobj = valobj.GetChildMemberWithName(name)
+    return valobj
+
+
+class Printer(object):
+    '''Base class for Printers'''
+
+    def __init__(self, valobj, dict={}):
+        self.valobj = valobj
+        self.initialize()
+
+    def initialize(self):
+        return None
+
+    def update(self):
+        return False
+
+    def num_children(self):
+        return 0
+
+    def has_children(self):
+        return False
+
+    def get_child_at_index(self, index):
+        return None
+
+    def get_child_index(self, name):
+        return None
+
+    def get_summary(self):
+        return None
+
+    def member(self, *chain):
+        '''Performs chained GetChildMemberWithName lookups'''
+        return member(self.valobj, *chain)
+
+    def template_params(self):
+        '''Returns list of template params values (as strings)'''
+        type_name = self.valobj.GetTypeName()
+        params = []
+        level = 0
+        start = 0
+        for i, c in enumerate(type_name):
+            if c == '<':
+                level += 1
+                if level == 1:
+                    start = i + 1
+            elif c == '>':
+                level -= 1
+                if level == 0:
+                    params.append(type_name[start:i].strip())
+            elif c == ',' and level == 1:
+                params.append(type_name[start:i].strip())
+                start = i + 1
+        return params
+
+    def template_param_at(self, index):
+        '''Returns template param value at index (as string)'''
+        return self.template_params()[index]
+
+
+class UtilsSlicePrinter(Printer):
+    '''Printer for tint::utils::Slice<T>'''
+
+    def initialize(self):
+        self.len = self.valobj.GetChildMemberWithName('len')
+        self.cap = self.valobj.GetChildMemberWithName('cap')
+        self.data = self.valobj.GetChildMemberWithName('data')
+        self.elem_type = self.data.GetType().GetPointeeType()
+        self.elem_size = self.elem_type.GetByteSize()
+
+    def get_summary(self):
+        return 'length={} capacity={}'.format(self.len.GetValueAsUnsigned(), self.cap.GetValueAsUnsigned())
+
+    def num_children(self):
+        # NOTE: VS Code on MacOS hangs if we try to expand something too large, so put an artificial limit
+        # until we can figure out how to know if this is a valid instance.
+        return min(self.len.GetValueAsUnsigned(), 256)
+
+    def has_children(self):
+        return True
+
+    def get_child_at_index(self, index):
+        try:
+            if not 0 <= index < self.num_children():
+                return None
+            # TODO: return self.value_at(index)
+            offset = index * self.elem_size
+            return self.data.CreateChildAtOffset('[%s]' % index, offset, self.elem_type)
+        except Exception as e:
+            log.error('%s', e)
+            raise
+
+    def value_at(self, index):
+        '''Returns array value at index'''
+        offset = index * self.elem_size
+        return self.data.CreateChildAtOffset('[%s]' % index, offset, self.elem_type)
+
+
+class UtilsVectorPrinter(Printer):
+    '''Printer for tint::utils::Vector<T, N>'''
+
+    def initialize(self):
+        self.slice = self.member('impl_', 'slice')
+        self.slice_printer = UtilsSlicePrinter(self.slice)
+        self.fixed_size = int(self.template_param_at(1))
+        self.cap = self.slice_printer.member('cap')
+
+    def get_summary(self):
+        using_heap = self.cap.GetValueAsUnsigned() > self.fixed_size
+        return 'heap={} {}'.format(using_heap, self.slice_printer.get_summary())
+
+    def num_children(self):
+        return self.slice_printer.num_children()
+
+    def has_children(self):
+        return self.slice_printer.has_children()
+
+    def get_child_at_index(self, index):
+        return self.slice_printer.get_child_at_index(index)
+
+    def make_slice_printer(self):
+        return UtilsSlicePrinter(self.slice)
+
+
+class UtilsVectorRefPrinter(Printer):
+    '''Printer for tint::utils::VectorRef<T>'''
+
+    def initialize(self):
+        self.slice = self.member('slice_')
+        self.slice_printer = UtilsSlicePrinter(self.slice)
+        self.can_move = self.member('can_move_')
+
+    def get_summary(self):
+        return 'can_move={} {}'.format(self.can_move.GetValue(), self.slice_printer.get_summary())
+
+    def num_children(self):
+        return self.slice_printer.num_children()
+
+    def has_children(self):
+        return self.slice_printer.has_children()
+
+    def get_child_at_index(self, index):
+        return self.slice_printer.get_child_at_index(index)
+
+
+class UtilsHashsetPrinter(Printer):
+    '''Printer for Hashset<T, N, HASH, EQUAL>'''
+
+    def initialize(self):
+        self.slice = UtilsVectorPrinter(
+            self.member('slots_')).make_slice_printer()
+
+        self.try_read_std_optional_func = self.try_read_std_optional
+
+    def update(self):
+        self.valid_slots = []
+        for slot in range(0, self.slice.num_children()):
+            v = self.slice.value_at(slot)
+            if member(v, 'hash').GetValueAsUnsigned() != 0:
+                self.valid_slots.append(slot)
+        return False
+
+    def get_summary(self):
+        return 'length={}'.format(self.num_children())
+
+    def num_children(self):
+        return len(self.valid_slots)
+
+    def has_children(self):
+        return True
+
+    def get_child_at_index(self, index):
+        slot = self.valid_slots[index]
+        v = self.slice.value_at(slot)
+        value = member(v, 'value')
+
+        # value is a std::optional, let's try to extract its value for display
+        kvp = self.try_read_std_optional_func(slot, value)
+        if kvp is None:
+            # If we failed, just output the slot and value as is, which will use
+            # the default printer for std::optional.
+            kvp = slot, value
+
+        return kvp[1].CreateChildAtOffset('[{}]'.format(kvp[0]), 0, kvp[1].GetType())
+
+    def try_read_std_optional(self, slot, value):
+        try:
+            # libc++
+            v = value.EvaluateExpression('__val_')
+            if v.name is not None:
+                return slot, v
+
+            # libstdc++
+            v = value.EvaluateExpression('_M_payload._M_payload._M_value')
+            if v.name is not None:
+                return slot, v
+            return None
+        except:
+            return None
+
+
+class UtilsHashmapPrinter(Printer):
+    '''Printer for Hashmap<K, V, N, HASH, EQUAL>'''
+
+    def initialize(self):
+        self.hash_set = UtilsHashsetPrinter(self.member('set_'))
+        # Replace the lookup function so we can extract the key and value out of the std::optionals in the Hashset
+        self.hash_set.try_read_std_optional_func = self.try_read_std_optional
+
+    def update(self):
+        self.hash_set.update()
+
+    def get_summary(self):
+        return self.hash_set.get_summary()
+
+    def num_children(self):
+        return self.hash_set.num_children()
+
+    def has_children(self):
+        return self.hash_set.has_children()
+
+    def get_child_at_index(self, index):
+        return self.hash_set.get_child_at_index(index)
+
+    def try_read_std_optional(self, slot, value):
+        try:
+            # libc++
+            val = value.EvaluateExpression('__val_')
+            k = val.EvaluateExpression('key')
+            v = val.EvaluateExpression('value')
+            if k.name is not None and v.name is not None:
+                return k.GetValue(), v
+
+            # libstdc++
+            val = value.EvaluateExpression('_M_payload._M_payload._M_value')
+            k = val.EvaluateExpression('key')
+            v = val.EvaluateExpression('value')
+            if k.name is not None and v.name is not None:
+                return k.GetValue(), v
+        except:
+            pass
+        # Failed, fall back on hash_set
+        return self.hash_set.try_read_std_optional(slot, value)
