diff --git a/README.md b/README.md
index 34f2488..e41b58b 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ For example, to build a COLRv1 font with a focus on [handwriting](https://rsheet
 ```bash
 pip install -e .
 nanoemoji --helpfull
-nanoemoji --color_format colr_1 $(find ../noto-emoji/svg -name 'emoji_u270d*.svg')
+nanoemoji --color_format glyf_colr_1 $(find ../noto-emoji/svg -name 'emoji_u270d*.svg')
 ```
 
 ## How to cut a new release
diff --git a/src/nanoemoji/nanoemoji.py b/src/nanoemoji/nanoemoji.py
index e60be5a..5b33782 100644
--- a/src/nanoemoji/nanoemoji.py
+++ b/src/nanoemoji/nanoemoji.py
@@ -61,7 +61,6 @@ class ColorFontConfig(NamedTuple):
     color_format: str
     output_format: str
     keep_glyph_names: bool = False
-    cff_version: int = 2
 
 
 class InputGlyph(NamedTuple):
@@ -80,19 +79,44 @@ class InputGlyph(NamedTuple):
 class ColorGenerator(NamedTuple):
     apply_ufo: Callable[[ufoLib2.Font, Sequence[ColorGlyph]], None]
     apply_ttfont: Callable[[ufoLib2.Font, Sequence[ColorGlyph], ttLib.TTFont], None]
+    font_ext: str  # extension for font binary, .ttf or .otf
 
 
 _COLOR_FORMAT_GENERATORS = {
-    "glyf": ColorGenerator(lambda *args: _glyf_ufo(*args), lambda *_: None),
-    "colr_0": ColorGenerator(lambda *args: _colr_ufo(0, *args), lambda *_: None),
-    "colr_1": ColorGenerator(lambda *args: _colr_ufo(1, *args), lambda *_: None),
-    "svg": ColorGenerator(lambda *_: None, lambda *args: _svg_ttfont(*args, zip=False)),
-    "svgz": ColorGenerator(lambda *_: None, lambda *args: _svg_ttfont(*args, zip=True)),
+    "glyf": ColorGenerator(lambda *args: _glyf_ufo(*args), lambda *_: None, ".ttf"),
+    "glyf_colr_0": ColorGenerator(
+        lambda *args: _colr_ufo(0, *args), lambda *_: None, ".ttf"
+    ),
+    "glyf_colr_1": ColorGenerator(
+        lambda *args: _colr_ufo(1, *args), lambda *_: None, ".ttf"
+    ),
+    "cff_colr_0": ColorGenerator(
+        lambda *args: _colr_ufo(0, *args), lambda *_: None, ".otf"
+    ),
+    "cff_colr_1": ColorGenerator(
+        lambda *args: _colr_ufo(1, *args), lambda *_: None, ".otf"
+    ),
+    "cff2_colr_0": ColorGenerator(
+        lambda *args: _colr_ufo(0, *args), lambda *_: None, ".otf"
+    ),
+    "cff2_colr_1": ColorGenerator(
+        lambda *args: _colr_ufo(1, *args), lambda *_: None, ".otf"
+    ),
+    "svg": ColorGenerator(
+        lambda *_: None, lambda *args: _svg_ttfont(*args, zip=False), ".ttf"
+    ),
+    "svgz": ColorGenerator(
+        lambda *_: None, lambda *args: _svg_ttfont(*args, zip=True), ".ttf"
+    ),
     "cbdt": ColorGenerator(
-        lambda *args: _not_impl("ufo", *args), lambda *args: _not_impl("TTFont", *args)
+        lambda *args: _not_impl("ufo", *args),
+        lambda *args: _not_impl("TTFont", *args),
+        ".ttf",
     ),
     "sbix": ColorGenerator(
-        lambda *args: _not_impl("ufo", *args), lambda *args: _not_impl("TTFont", *args)
+        lambda *args: _not_impl("ufo", *args),
+        lambda *args: _not_impl("TTFont", *args),
+        ".ttf",
     ),
 }
 
@@ -104,27 +128,24 @@ FLAGS = flags.FLAGS
 # TODO flag on/off shape reuse
 flags.DEFINE_integer("upem", 1024, "Units per em.")
 flags.DEFINE_string("family", "An Emoji Family", "Family name.")
+flags.DEFINE_string("output_dir", "/tmp", "Where to put the output.")
+flags.DEFINE_string(
+    "output_file",
+    None,
+    "Output filename. By default derived from --output_dir and --family",
+)
 flags.DEFINE_enum(
     "color_format",
-    "colr_0",
+    "glyf_colr_0",
     sorted(_COLOR_FORMAT_GENERATORS.keys()),
-    "Type of color font to generate.",
+    "Type of font to generate.",
 )
-flags.DEFINE_string(
-    "output_file",
-    "/tmp/AnEmojiFamily-Regular.ttf",
-    "Dest file, can be .ttf, .otf, or .ufo",
+flags.DEFINE_enum(
+    "output", "font", ["ufo", "font"], "Whether to output a font binary or a UFO"
 )
 flags.DEFINE_bool(
     "keep_glyph_names", False, "Whether or not to store glyph names in the font."
 )
-flags.DEFINE_integer(
-    "cff_version",
-    2,
-    "The CFF table format version. Choose 1 or 2 (default: 2)",
-    lower_bound=1,
-    upper_bound=2,
-)
 
 
 def _codepoints_from_filename(filename):
@@ -183,8 +204,11 @@ def _make_ttfont(config, ufo, color_glyphs):
     if config.output_format == ".ttf":
         ttfont = ufo2ft.compileTTF(ufo, overlapsBackend="pathops")
     if config.output_format == ".otf":
+        cff_version = 1
+        if config.color_format.startswith("cff2_"):
+            cff_version = 2
         ttfont = ufo2ft.compileOTF(
-            ufo, cffVersion=config.cff_version, overlapsBackend="pathops"
+            ufo, cffVersion=cff_version, overlapsBackend="pathops"
         )
 
     if not ttfont:
@@ -462,13 +486,16 @@ def _generate_color_font(config: ColorFontConfig, inputs: Iterable[InputGlyph]):
 
 
 def _run(argv):
+    if FLAGS.output == "ufo":
+        output_format = "ufo"
+    else:
+        output_format = _COLOR_FORMAT_GENERATORS[FLAGS.color_format].font_ext
     config = ColorFontConfig(
         upem=FLAGS.upem,
         family=FLAGS.family,
         color_format=FLAGS.color_format,
-        output_format=os.path.splitext(FLAGS.output_file)[1],
+        output_format=output_format,
         keep_glyph_names=FLAGS.keep_glyph_names,
-        cff_version=FLAGS.cff_version,
     )
 
     inputs = list(_inputs(argv[1:]))
@@ -478,8 +505,12 @@ def _run(argv):
 
     ufo, ttfont = _generate_color_font(config, inputs)
 
-    _write(ufo, ttfont, FLAGS.output_file)
-    logging.info("Wrote %s" % FLAGS.output_file)
+    output_file = FLAGS.output_file
+    if output_file is None:
+        output_file = f"{FLAGS.family.replace(' ', '')}{output_format}"
+    output_file = os.path.join(FLAGS.output_dir, output_file)
+    _write(ufo, ttfont, output_file)
+    logging.info("Wrote %s" % output_file)
 
 
 def main():

Some combinations of flags don't make sense
As @anthrotype noted `--color_format` and `--output_file` have begun to overlap. For example, setting `--color_format glyf --output_file my.otf` feels odd. Clean this up.

> while working on #52 I came across the fact that "glyf" as a --color_format and _glyf_ufo as function name in here don't make much sense when --output_format is .otf (i.e. CFF-flavored OpenType). The name glyf is tied to TrueType. We want to convey the idea that this is not a layered font (like COLR is), and that it is not colored as it only has black & white (or if you like, only black). How about nouns like "flat", or "black"? Or even just "simple" or "normal"..

diff --git a/tests/make_emoji_font_test.py b/tests/make_emoji_font_test.py
index f0fe893..a7e2fb0 100644
--- a/tests/make_emoji_font_test.py
+++ b/tests/make_emoji_font_test.py
@@ -55,27 +55,32 @@ def test_codepoints_from_filename(filename, codepoints):
         # verify glyf removes component if there is only one shape
         (("one_rect.svg",), "one_rect_glyf.ttx", "glyf", ".ttf"),
         # simple fill on rect
-        (("rect.svg",), "rect_colr_0.ttx", "colr_0", ".ttf"),
-        (("rect.svg",), "rect_colr_1.ttx", "colr_1", ".ttf"),
+        (("rect.svg",), "rect_colr_0.ttx", "glyf_colr_0", ".ttf"),
+        (("rect.svg",), "rect_colr_1.ttx", "glyf_colr_1", ".ttf"),
         (("rect.svg",), "rect_svg.ttx", "svg", ".ttf"),
         # linear gradient on rect
         (
             ("linear_gradient_rect.svg",),
             "linear_gradient_rect_colr_1.ttx",
-            "colr_1",
+            "glyf_colr_1",
             ".ttf",
         ),
         # radial gradient on rect
         (
             ("radial_gradient_rect.svg",),
             "radial_gradient_rect_colr_1.ttx",
-            "colr_1",
+            "glyf_colr_1",
             ".ttf",
         ),
         # reuse shape in different color
-        (("rect.svg", "rect2.svg"), "rects_colr_1.ttx", "colr_1", ".ttf"),
+        (("rect.svg", "rect2.svg"), "rects_colr_1.ttx", "glyf_colr_1", ".ttf"),
         # clocks have composites, reuse of composite, and reuse of shape w/diff color
-        (("one-o-clock.svg", "two-o-clock.svg"), "clocks_colr_1.ttx", "colr_1", ".ttf"),
+        (
+            ("one-o-clock.svg", "two-o-clock.svg"),
+            "clocks_colr_1.ttx",
+            "glyf_colr_1",
+            ".ttf",
+        ),
         (("one-o-clock.svg", "two-o-clock.svg"), "clocks_glyf.ttx", "glyf", ".ttf"),
         (("one-o-clock.svg", "two-o-clock.svg"), "clocks_svg.ttx", "svg", ".ttf"),
         # clocks share shapes, rects share shapes. Should be two distinct svgs in font.
@@ -103,7 +108,7 @@ def test_make_emoji_font(svgs, expected_ttx, color_format, output_format):
 @pytest.mark.parametrize(
     "svgs", [("rect.svg", "rect2.svg"), ("one-o-clock.svg", "two-o-clock.svg")]
 )
-@pytest.mark.parametrize("color_format", ["colr_0", "colr_1", "svg", "svgz"])
+@pytest.mark.parametrize("color_format", ["glyf_colr_0", "glyf_colr_1", "svg", "svgz"])
 @pytest.mark.parametrize("keep_glyph_names", [True, False])
 def test_keep_glyph_names(svgs, color_format, keep_glyph_names):
     config, glyph_inputs = test_helper.color_font_config(
diff --git a/tests/svg_colr_svg_test.py b/tests/svg_colr_svg_test.py
index 182e46a..4dd1ab7 100644
--- a/tests/svg_colr_svg_test.py
+++ b/tests/svg_colr_svg_test.py
@@ -24,8 +24,8 @@ from colr_to_svg import colr_to_svg
     "svg_in, expected_svg_out, color_format, output_format",
     [
         # simple fill on rect
-        ("rect.svg", "rect_from_colr_0.svg", "colr_0", ".ttf"),
-        ("rect.svg", "rect_from_colr_1.svg", "colr_1", ".ttf"),
+        ("rect.svg", "rect_from_colr_0.svg", "glyf_colr_0", ".ttf"),
+        ("rect.svg", "rect_from_colr_1.svg", "glyf_colr_1", ".ttf"),
         # linear gradient on rect
         # ("linear_gradient_rect.svg", "linear_gradient_rect.ttx", "colr_1", ".ttf"),
         # radial gradient on rect

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
3.7
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
absl-py==0.9.0
appdirs==1.4.4
attrs==19.3.0
booleanOperations==0.9.0
certifi @ file:///croot/certifi_1671487769961/work/certifi
cffsubr==0.2.7
compreffor==0.5.0
cu2qu==1.6.7
exceptiongroup==1.2.2
fonttools==4.12.0
fs==2.4.11
importlib-metadata==6.7.0
iniconfig==2.0.0
lxml==4.5.0
-e git+https://github.com/googlefonts/nanoemoji.git@d7a332fdd6f517474377c1b736bc502732f409a8#egg=nanoemoji
packaging==24.0
picosvg==0.3.10
pluggy==1.2.0
pyclipper==1.1.0.post3
pytest==7.4.4
pytz==2020.1
regex==2020.5.14
six==1.15.0
skia-pathops==0.4.1
tomli==2.0.1
typing_extensions==4.7.1
ufo2ft==2.15.0
ufoLib2==0.6.2
zipp==3.15.0

name: nanoemoji
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
  - certifi=2022.12.7=py37h06a4308_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=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - absl-py==0.9.0
      - appdirs==1.4.4
      - attrs==19.3.0
      - booleanoperations==0.9.0
      - cffsubr==0.2.7
      - compreffor==0.5.0
      - cu2qu==1.6.7
      - exceptiongroup==1.2.2
      - fonttools==4.12.0
      - fs==2.4.11
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - lxml==4.5.0
      - packaging==24.0
      - picosvg==0.3.10
      - pluggy==1.2.0
      - pyclipper==1.1.0.post3
      - pytest==7.4.4
      - pytz==2020.1
      - regex==2020.5.14
      - six==1.15.0
      - skia-pathops==0.4.1
      - tomli==2.0.1
      - typing-extensions==4.7.1
      - ufo2ft==2.15.0
      - ufolib2==0.6.2
      - zipp==3.15.0
prefix: /opt/conda/envs/nanoemoji

tests/make_emoji_font_test.py::test_make_emoji_font[svgs1-rect_colr_0.ttx-glyf_colr_0-.ttf] tests/make_emoji_font_test.py::test_make_emoji_font[svgs2-rect_colr_1.ttx-glyf_colr_1-.ttf] tests/make_emoji_font_test.py::test_make_emoji_font[svgs4-linear_gradient_rect_colr_1.ttx-glyf_colr_1-.ttf] tests/make_emoji_font_test.py::test_make_emoji_font[svgs5-radial_gradient_rect_colr_1.ttx-glyf_colr_1-.ttf] tests/make_emoji_font_test.py::test_make_emoji_font[svgs6-rects_colr_1.ttx-glyf_colr_1-.ttf] tests/make_emoji_font_test.py::test_make_emoji_font[svgs7-clocks_colr_1.ttx-glyf_colr_1-.ttf] tests/make_emoji_font_test.py::test_keep_glyph_names[True-glyf_colr_0-svgs0] tests/make_emoji_font_test.py::test_keep_glyph_names[True-glyf_colr_0-svgs1] tests/make_emoji_font_test.py::test_keep_glyph_names[True-glyf_colr_1-svgs0] tests/make_emoji_font_test.py::test_keep_glyph_names[True-glyf_colr_1-svgs1] tests/make_emoji_font_test.py::test_keep_glyph_names[False-glyf_colr_0-svgs0] tests/make_emoji_font_test.py::test_keep_glyph_names[False-glyf_colr_0-svgs1] tests/make_emoji_font_test.py::test_keep_glyph_names[False-glyf_colr_1-svgs0] tests/make_emoji_font_test.py::test_keep_glyph_names[False-glyf_colr_1-svgs1] tests/svg_colr_svg_test.py::test_svg_to_colr_to_svg[rect.svg-rect_from_colr_0.svg-glyf_colr_0-.ttf] tests/svg_colr_svg_test.py::test_svg_to_colr_to_svg[rect.svg-rect_from_colr_1.svg-glyf_colr_1-.ttf]
tests/make_emoji_font_test.py::test_codepoints_from_filename[emoji_u1f378.svg-codepoints0] tests/make_emoji_font_test.py::test_codepoints_from_filename[emoji_u1f385_1f3fb.svg-codepoints1] tests/make_emoji_font_test.py::test_codepoints_from_filename[emoji_u1f469_1f3fd_200d_1f91d_200d_1f468_1f3ff.svg-codepoints2] tests/make_emoji_font_test.py::test_codepoints_from_filename[2198.svg-codepoints3] tests/make_emoji_font_test.py::test_codepoints_from_filename[1f9d1-200d-1f91d-200d-1f9d1.svg-codepoints4] tests/make_emoji_font_test.py::test_make_emoji_font[svgs0-one_rect_glyf.ttx-glyf-.ttf] tests/make_emoji_font_test.py::test_make_emoji_font[svgs3-rect_svg.ttx-svg-.ttf] tests/make_emoji_font_test.py::test_make_emoji_font[svgs8-clocks_glyf.ttx-glyf-.ttf] tests/make_emoji_font_test.py::test_make_emoji_font[svgs9-clocks_svg.ttx-svg-.ttf] tests/make_emoji_font_test.py::test_make_emoji_font[svgs10-clocks_rects_svg.ttx-svg-.ttf] tests/make_emoji_font_test.py::test_keep_glyph_names[True-svg-svgs0] tests/make_emoji_font_test.py::test_keep_glyph_names[True-svg-svgs1] tests/make_emoji_font_test.py::test_keep_glyph_names[True-svgz-svgs0] tests/make_emoji_font_test.py::test_keep_glyph_names[True-svgz-svgs1] tests/make_emoji_font_test.py::test_keep_glyph_names[False-svg-svgs0] tests/make_emoji_font_test.py::test_keep_glyph_names[False-svg-svgs1] tests/make_emoji_font_test.py::test_keep_glyph_names[False-svgz-svgs0] tests/make_emoji_font_test.py::test_keep_glyph_names[False-svgz-svgs1]
src/nanoemoji/nanoemoji.py README.md
src/nanoemoji/nanoemoji.py README.md