diff --git a/CHANGELOG.md b/CHANGELOG.md
index ae31082..b55a868 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,6 +27,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
   the proportion of the table.  For example, setting the "max" key to
   0.5 means that the key should exceed half of the total table width.
 
+- When operating non-interactively, by default the width is now
+  expanded to accommodate the content.  To force a particular table
+  width in this situation, set the table's width using the "width_"
+  style attribute.
 
 ## [0.4.1] - 2019-10-02
 
diff --git a/pyout/common.py b/pyout/common.py
index 0bf2484..0aaac98 100644
--- a/pyout/common.py
+++ b/pyout/common.py
@@ -371,6 +371,10 @@ class StyleFields(object):
         visible = self.visible_columns
         autowidth_columns = self.autowidth_columns
         width_table = self.style["width_"]
+        if width_table is None:
+            # The table is unbounded (non-interactive).
+            return
+
         if len(visible) > width_table:
             raise elements.StyleError(
                 "Number of visible columns exceeds available table width")
@@ -431,7 +435,10 @@ class StyleFields(object):
 
         width_table = self.style["width_"]
         width_fixed = self.width_fixed
-        width_auto = width_table - width_fixed
+        if width_table is None:
+            width_auto = float("inf")
+        else:
+            width_auto = width_table - width_fixed
 
         if not autowidth_columns:
             return False
@@ -502,7 +509,7 @@ class StyleFields(object):
                available characters the column should claim at a time.  This is
                only in effect after each column has claimed one, and the
                specific column has claimed its minimum.
-        available : int
+        available : int or float('inf')
             Width available to be assigned.
 
         Returns
@@ -551,7 +558,7 @@ class StyleFields(object):
                         claim, available, column)
                 if available == 0:
                     break
-        lgr.debug("Available width after assigned: %d", available)
+        lgr.debug("Available width after assigned: %s", available)
         lgr.debug("Assigned widths: %r", assigned)
         return assigned
 
diff --git a/pyout/elements.py b/pyout/elements.py
index 716a325..fef77f4 100644
--- a/pyout/elements.py
+++ b/pyout/elements.py
@@ -215,9 +215,13 @@ schema = {
             "scope": "table"},
         "width_": {
             "description": """Total width of table.
-            This is typically not set directly by the user.""",
-            "default": 90,
-            "type": "integer",
+            This is typically not set directly by the user.  With the default
+            null value, the width is set to the stream's width for interactive
+            streams and as wide as needed to fit the content for
+            non-interactive streams.""",
+            "default": None,
+            "oneOf": [{"type": "integer"},
+                      {"type": "null"}],
             "scope": "table"}
     },
     # All other keys are column names.
diff --git a/pyout/interface.py b/pyout/interface.py
index 3050cf4..805108c 100644
--- a/pyout/interface.py
+++ b/pyout/interface.py
@@ -125,7 +125,7 @@ class Writer(object):
             self.mode = "final"
 
         style = style or {}
-        if "width_" not in style and self._stream.width:
+        if style.get("width_") is None:
             lgr.debug("Setting width to stream width: %s",
                       self._stream.width)
             style["width_"] = self._stream.width

diff --git a/pyout/tests/test_tabular.py b/pyout/tests/test_tabular.py
index 945840b..fbb67b3 100644
--- a/pyout/tests/test_tabular.py
+++ b/pyout/tests/test_tabular.py
@@ -133,6 +133,36 @@ def test_tabular_width_no_style():
     assert out.stdout == "a" * 97 + "...\n"
 
 
+def test_tabular_width_non_interactive_default():
+    out = Tabular(["name", "status"], interactive=False)
+    a = "a" * 70
+    b = "b" * 100
+    with out:
+        out([a, b])
+    assert out.stdout == "{} {}\n".format(a, b)
+
+
+def test_tabular_width_non_interactive_width_override():
+    out = Tabular(["name", "status"],
+                  style={"width_": 31,
+                         "default_": {"width": {"marker": "…"}}},
+                  interactive=False)
+    with out:
+        out(["a" * 70, "b" * 100])
+    stdout = out.stdout
+    assert stdout == "{} {}\n".format("a" * 14 + "…", "b" * 14 + "…")
+
+
+def test_tabular_width_non_interactive_col_max():
+    out = Tabular(["name", "status"],
+                  style={"status": {"width": {"max": 20, "marker": "…"}}},
+                  interactive=False)
+    with out:
+        out(["a" * 70, "b" * 100])
+    stdout = out.stdout
+    assert stdout == "{} {}\n".format("a" * 70, "b" * 19 + "…")
+
+
 def test_tabular_write_header():
     out = Tabular(["name", "status"],
                   style={"header_": {},

Make width as large as needed in "final" mode
If stdout it not a tty ATM pytout seems to limit to some predetermined width:
```shell
$> datalad ls -r ~/datalad -L | cat 
[3]  - 3355 done       gitk --all
PATH              TYPE  BRANCH DESCRIBE DATE          CLEAN ANNEX(PRESENT) ANNEX(WORKTREE)
/home/yoh/datalad annex master          2018-09-17... -     31.3 MB        23.8 MB        
/home/yoh/data... annex master 0.0.2... 2018-06-08... X     0 Bytes        0 Bytes        
/home/yoh/data... annex master          2018-06-08... X     0 Bytes        0 Bytes        
...
```
but since delivering the "final" rendering -- why not to make it as wide as needed?  
Also then It would correspond to the final version of the "update" mode output
pyout/tests/test_tabular.py::test_tabular_width_non_interactive_default pyout/tests/test_tabular.py::test_tabular_width_non_interactive_col_max
pyout/tests/test_tabular.py::test_tabular_write_color pyout/tests/test_tabular.py::test_tabular_write_empty_string pyout/tests/test_tabular.py::test_tabular_write_missing_column pyout/tests/test_tabular.py::test_tabular_write_missing_column_missing_text pyout/tests/test_tabular.py::test_tabular_write_list_value pyout/tests/test_tabular.py::test_tabular_write_missing_column_missing_object_data pyout/tests/test_tabular.py::test_tabular_write_columns_from_orderdict_row pyout/tests/test_tabular.py::test_tabular_write_columns_orderdict_mapping[sequence] pyout/tests/test_tabular.py::test_tabular_write_columns_orderdict_mapping[dict] pyout/tests/test_tabular.py::test_tabular_write_data_as_list pyout/tests/test_tabular.py::test_tabular_width_no_style pyout/tests/test_tabular.py::test_tabular_width_non_interactive_width_override pyout/tests/test_tabular.py::test_tabular_write_header pyout/tests/test_tabular.py::test_tabular_write_data_as_object pyout/tests/test_tabular.py::test_tabular_write_different_data_types_same_output pyout/tests/test_tabular.py::test_tabular_write_header_with_style pyout/tests/test_tabular.py::test_tabular_nondefault_separator pyout/tests/test_tabular.py::test_tabular_write_data_as_list_no_columns pyout/tests/test_tabular.py::test_tabular_write_style_override pyout/tests/test_tabular.py::test_tabular_default_style pyout/tests/test_tabular.py::test_tabular_write_multicolor pyout/tests/test_tabular.py::test_tabular_write_all_whitespace_nostyle pyout/tests/test_tabular.py::test_tabular_write_style_flanking pyout/tests/test_tabular.py::test_tabular_write_align pyout/tests/test_tabular.py::test_tabular_rewrite pyout/tests/test_tabular.py::test_tabular_rewrite_with_header pyout/tests/test_tabular.py::test_tabular_rewrite_multi_id pyout/tests/test_tabular.py::test_tabular_rewrite_multi_value pyout/tests/test_tabular.py::test_tabular_rewrite_auto_width pyout/tests/test_tabular.py::test_tabular_non_hashable_id_error pyout/tests/test_tabular.py::test_tabular_write_lookup_color pyout/tests/test_tabular.py::test_tabular_write_lookup_bold pyout/tests/test_tabular.py::test_tabular_write_lookup_bold_false pyout/tests/test_tabular.py::test_tabular_write_lookup_non_hashable pyout/tests/test_tabular.py::test_tabular_write_re_lookup_color pyout/tests/test_tabular.py::test_tabular_write_re_lookup_bold pyout/tests/test_tabular.py::test_tabular_write_intervals_wrong_type pyout/tests/test_tabular.py::test_tabular_write_intervals_color pyout/tests/test_tabular.py::test_tabular_write_intervals_color_open_ended pyout/tests/test_tabular.py::test_tabular_write_intervals_color_catchall_range pyout/tests/test_tabular.py::test_tabular_write_intervals_color_outside_intervals pyout/tests/test_tabular.py::test_tabular_write_intervals_bold pyout/tests/test_tabular.py::test_tabular_write_intervals_missing pyout/tests/test_tabular.py::test_tabular_write_transform pyout/tests/test_tabular.py::test_tabular_write_transform_with_header pyout/tests/test_tabular.py::test_tabular_write_transform_autowidth pyout/tests/test_tabular.py::test_tabular_write_transform_on_header pyout/tests/test_tabular.py::test_tabular_write_transform_func_error pyout/tests/test_tabular.py::test_tabular_write_width_truncate_long pyout/tests/test_tabular.py::test_tabular_write_autowidth pyout/tests/test_tabular.py::test_tabular_write_autowidth_with_header pyout/tests/test_tabular.py::test_tabular_write_autowidth_min pyout/tests/test_tabular.py::test_tabular_write_autowidth_min_max[marker=True] pyout/tests/test_tabular.py::test_tabular_write_autowidth_min_max[marker=False] pyout/tests/test_tabular.py::test_tabular_write_autowidth_min_max[marker=\u2026] pyout/tests/test_tabular.py::test_tabular_write_autowidth_min_max_with_header pyout/tests/test_tabular.py::test_tabular_write_autowidth_min_frac pyout/tests/test_tabular.py::test_tabular_write_autowidth_max_frac pyout/tests/test_tabular.py::test_tabular_write_fixed_width_frac pyout/tests/test_tabular.py::test_tabular_write_autowidth_different_data_types_same_output pyout/tests/test_tabular.py::test_tabular_write_incompatible_width_exception pyout/tests/test_tabular.py::test_tabular_fixed_width_exceeds_total pyout/tests/test_tabular.py::test_tabular_number_of_columns_exceeds_total_width pyout/tests/test_tabular.py::test_tabular_auto_width_exceeds_total pyout/tests/test_tabular.py::test_tabular_auto_width_exceeds_total_multiline pyout/tests/test_tabular.py::test_tabular_write_callable_values pyout/tests/test_tabular.py::test_tabular_write_callable_transform_nothing pyout/tests/test_tabular.py::test_tabular_write_callable_re_lookup_non_string pyout/tests/test_tabular.py::test_tabular_write_callable_values_multi_return pyout/tests/test_tabular.py::test_tabular_callback_to_offscreen_row[20] pyout/tests/test_tabular.py::test_tabular_callback_to_offscreen_row[21] pyout/tests/test_tabular.py::test_tabular_write_callable_values_multicol_key_infer_column[result=tuple] pyout/tests/test_tabular.py::test_tabular_write_callable_values_multicol_key_infer_column[result=dict] pyout/tests/test_tabular.py::test_tabular_write_generator_function_values[gen_func] pyout/tests/test_tabular.py::test_tabular_write_generator_function_values[generator] pyout/tests/test_tabular.py::test_tabular_write_generator_values_multireturn pyout/tests/test_tabular.py::test_tabular_write_wait_noop_if_nothreads pyout/tests/test_tabular.py::test_tabular_write_delayed[dict] pyout/tests/test_tabular.py::test_tabular_write_delayed[list] pyout/tests/test_tabular.py::test_tabular_write_delayed[attrs] pyout/tests/test_tabular.py::test_tabular_write_inspect_with_getitem pyout/tests/test_tabular.py::test_tabular_hidden_column pyout/tests/test_tabular.py::test_tabular_hidden_if_missing_column pyout/tests/test_tabular.py::test_tabular_hidden_col_takes_back_auto_space pyout/tests/test_tabular.py::test_tabular_summary pyout/tests/test_tabular.py::test_tabular_shrinking_summary pyout/tests/test_tabular.py::test_tabular_mode_invalid pyout/tests/test_tabular.py::test_tabular_mode_default pyout/tests/test_tabular.py::test_tabular_mode_after_write pyout/tests/test_tabular.py::test_tabular_mode_update_noninteractive pyout/tests/test_tabular.py::test_tabular_mode_incremental pyout/tests/test_tabular.py::test_tabular_mode_final pyout/tests/test_tabular.py::test_tabular_mode_final_summary