diff --git a/README.rst b/README.rst
index ae7af94..3b949a3 100644
--- a/README.rst
+++ b/README.rst
@@ -26,11 +26,9 @@ getkey
 
 Gets a "key" from the ``infile`` and returns it to the user, where "key" is a character, glyph, or string describing a control key.
 
-Currently supports parsing ASCII, UTF-8, and tab.
-Any other keys entered (such as arrow keys, UTF-16, etc) will result in returning individual bytes, one at a time.
-
-The tab key is represented as a string: 'TAB'.  This is not a "character", but it *is* a "key".  The implementation
-of keys may change in the future, but for now this seems to be simple and clear.
+Currently supports parsing ASCII, UTF-8, and some `special characters`_ as listed below.
+Any other keys entered will result in returning individual bytes, one at a time.
+*Pull requests adding special key support are welcome*
 
 Parameters:
 
@@ -40,6 +38,21 @@ Returns:
 
 * ``key`` - a string value corresponding to the key read in from the TTY ('a', 'B', '-', '☢', 'TAB', etc).
 
+Special Characters
+==================
+The following special characters are supported for VT220-like terminals.  This is all I personally have to test on,
+but pull reqeusts with additional support are welcome.  Issue #14 will make integration of new keys easier.
+
+Currently, special keys are supported by returning their name as a string, instead of a single character or glyph, as ASCII and UTF-8 do.
+This is not a "character", but it *is* a "key".  The implementation
+of keys may change in the future, but for now this seems to be simple and clear.
+
+* TAB
+* UP
+* DOWN
+* LEFT
+* RIGHT
+
 contribution
 ============
 
diff --git a/ugetch/__init__.py b/ugetch/__init__.py
index b615ca3..8d714da 100644
--- a/ugetch/__init__.py
+++ b/ugetch/__init__.py
@@ -65,11 +65,42 @@ def tab_parser(infile):
     return key
 
 
+def arrow_parser(infile):
+    '''Parse arrow keys'''
+    first_byte = _get_byte(infile)
+    key = None
+    if first_byte == 27:
+        # escape.  Check for bracket
+        second_byte = _get_byte(infile)
+        if second_byte == 91:
+            # final byte
+            final_byte = _get_byte(infile)
+            if final_byte == 65:
+                key = 'UP'
+            elif final_byte == 66:
+                key = 'DOWN'
+            elif final_byte == 67:
+                key = 'RIGHT'
+            elif final_byte == 68:
+                key = 'LEFT'
+            else:
+                _put_byte(first_byte)
+                _put_byte(second_byte)
+                _put_byte(final_byte)
+        else:
+            _put_byte(first_byte)
+            _put_byte(second_byte)
+    else:
+        _put_byte(first_byte)
+    return key
+
+
 # [ Global ]
 _DEFAULT=object()  # enable dynamic defaults
-# Tab needs to go before the ASCII parser, because it is technically in the ASCII range,
-#  and would be sucked in raw by the ASCII parser.
-_KEY_PARSERS=[tab_parser, ascii_parser, utf8_parser]  # ways to parse keys from byte lists
+# Special key parsers need to go before the ASCII parser, because
+#   their first byte is generally in the ASCII range,
+#   and would be sucked in raw by the ASCII parser.
+_KEY_PARSERS=[tab_parser, arrow_parser, ascii_parser, utf8_parser]  # ways to parse keys from byte lists
 _BYTES=[]  # byte buffer from the input file
 
 

implement arrow key support
diff --git a/test_ugetch.py b/test_ugetch.py
index 072b7bf..498adbd 100644
--- a/test_ugetch.py
+++ b/test_ugetch.py
@@ -34,7 +34,7 @@ def assert_expected(p, expected):
     '''Assert that we get the expected value'''
     index = p.expect_exact([expected, pexpect.EOF, pexpect.TIMEOUT])
     assert index == 0, "did not find expected ({}) in output ({})".format(
-        value, p.before
+        expected, p.before
     )
 
 
@@ -44,7 +44,7 @@ def in_vs_out(input_values):
     p = start_cli_shim()
     # test each char
     for value in input_values:
-        p.expect_exact("hit a key to print its representation: ")
+        assert_expected(p, "hit a key to print its representation: ")
         p.send(value)
         assert_expected(p, value)
 
@@ -74,6 +74,24 @@ def test_getch_tab():
     assert_expected(p, 'TAB')
 
 
+def test_getch_arrows():
+    # get shim
+    p = start_cli_shim()
+    # test each arrow
+    KEY_UP = '\x1b[A'
+    KEY_DOWN = '\x1b[B'
+    KEY_RIGHT = '\x1b[C'
+    KEY_LEFT = '\x1b[D'
+    p.send(KEY_UP)
+    assert_expected(p, 'UP')
+    p.send(KEY_DOWN)
+    assert_expected(p, 'DOWN')
+    p.send(KEY_LEFT)
+    assert_expected(p, 'LEFT')
+    p.send(KEY_RIGHT)
+    assert_expected(p, 'RIGHT')
+
+
 if __name__ == '__main__':
     import cProfile
     cProfile.run("test_getch_ascii()")

pip install -e .
parse_log_pytest
pytest
pytest pexpect pytest-cache
apt-get update apt-get install -y gcc
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
execnet==2.1.1
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
packaging @ file:///croot/packaging_1734472117206/work
pexpect==4.9.0
pluggy @ file:///croot/pluggy_1733169602837/work
ptyprocess==0.7.0
pytest @ file:///croot/pytest_1738938843180/work
pytest-cache==1.0
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
-e git+https://github.com/toejough/ugetch.git@ddf84a5577fa1b7341dd404bdf5b5e9b9a43cf72#egg=ugetch

name: ugetch
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py39h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.2=py39h06a4308_0
  - pip=25.0=py39h06a4308_0
  - pluggy=1.5.0=py39h06a4308_0
  - pytest=8.3.4=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py39h06a4308_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - execnet==2.1.1
      - pexpect==4.9.0
      - ptyprocess==0.7.0
      - pytest-cache==1.0
prefix: /opt/conda/envs/ugetch

test_ugetch.py::test_getch_arrows
test_ugetch.py::test_getch_ascii test_ugetch.py::test_getch_utf8 test_ugetch.py::test_getch_tab
README.rst ugetch/__init__.py
README.rst ugetch/__init__.py