diff --git a/pyproject.toml b/pyproject.toml
index 22220a9..9bbd0af 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -83,7 +83,7 @@ max-branches = 18
 max-statements = 67
 
 [tool.ruff.per-file-ignores]
-"test/*" = ["I"]
+"test/*" = ["I", "S"]
 "test/integration/*" = [
     "F523",
     "F821",
diff --git a/src/flynt/__init__.py b/src/flynt/__init__.py
index 5f94a49..0019830 100644
--- a/src/flynt/__init__.py
+++ b/src/flynt/__init__.py
@@ -2,7 +2,7 @@
 from old "%-formatted" and .format(...) strings into Python 3.6+'s f-strings.
 Learn more about f-strings at https://www.python.org/dev/peps/pep-0498/"""
 
-__version__ = "1.0.0"
+__version__ = "1.0.1"
 
 from flynt.cli import main
 
diff --git a/src/flynt/static_join/transformer.py b/src/flynt/static_join/transformer.py
index 7314b1a..8e86896 100644
--- a/src/flynt/static_join/transformer.py
+++ b/src/flynt/static_join/transformer.py
@@ -42,6 +42,10 @@ class JoinTransformer(ast.NodeTransformer):
 def transform_join(tree: ast.AST, *args, **kwargs) -> Tuple[str, bool]:
 
     jt = JoinTransformer()
-    jt.visit(tree)
-    new_code = fixup_transformed(tree)
-    return new_code, jt.counter > 0
+    new_tree = jt.visit(tree)
+    changed = jt.counter > 0
+    if changed:
+        new_code = fixup_transformed(new_tree)
+    else:
+        new_code = ""
+    return new_code, changed
diff --git a/src/flynt/string_concat/transformer.py b/src/flynt/string_concat/transformer.py
index 31fadb3..8276c3c 100644
--- a/src/flynt/string_concat/transformer.py
+++ b/src/flynt/string_concat/transformer.py
@@ -65,6 +65,9 @@ def transform_concat(tree: ast.AST, *args, **kwargs) -> Tuple[str, bool]:
 
     ft = ConcatTransformer()
     new = ft.visit(tree)
-    new_code = fixup_transformed(new)
-
-    return new_code, ft.counter > 0
+    changed = ft.counter > 0
+    if changed:
+        new_code = fixup_transformed(new)
+    else:
+        new_code = ""
+    return new_code, changed
diff --git a/src/flynt/utils/utils.py b/src/flynt/utils/utils.py
index 7db23ef..a97b21b 100644
--- a/src/flynt/utils/utils.py
+++ b/src/flynt/utils/utils.py
@@ -101,7 +101,18 @@ def ast_string_node(string: str) -> ast.Str:
     return ast.Str(s=string)
 
 
+def check_is_string_node(tree: ast.AST):
+    """Raise an exception is tree doesn't represent a string"""
+    if isinstance(tree, ast.Module):
+        tree = tree.body[0]
+    if isinstance(tree, ast.Expr):
+        tree = tree.value
+    assert isinstance(tree, (ast.JoinedStr, ast.Str)), f"found {type(tree)}"
+
+
 def fixup_transformed(tree: ast.AST, quote_type: Optional[str] = None) -> str:
+    """Given a transformed string / fstring ast node, transform it to a string."""
+    # check_is_string_node(tree)
     il = FstrInliner()
     il.visit(tree)
     new_code = ast_to_string(tree)
@@ -112,6 +123,7 @@ def fixup_transformed(tree: ast.AST, quote_type: Optional[str] = None) -> str:
         new_code = set_quote_type(new_code, quote_type)
     new_code = new_code.replace("\n", "\\n")
     new_code = new_code.replace("\t", "\\t")
+    # ast.parse(new_code)
     return new_code
 
 

diff --git a/test/test_edits.py b/test/test_edits.py
index 93e327f..cefda7d 100644
--- a/test/test_edits.py
+++ b/test/test_edits.py
@@ -663,3 +663,12 @@ def test_literal_direct(state: State):
     out, count = code_editor.fstringify_code_by_line(s_in, state)
     assert count == 1
     assert out == expected_out
+
+
+def test_joins():
+
+    s_in = """';'.join(['a', 'b', 'c'])"""
+    expected_out = '"a;b;c"'
+    out, count = code_editor.fstringify_static_joins(s_in, State())
+    assert count > 0
+    assert out == expected_out

transform-joins breaks code
Here's my flynt output:
```
Running flynt v.1.0.0
Using config file at /asdf/qwer/pyproject.toml
Using following options: Namespace(verbose=True, quiet=False, no_multiline=False, line_length=88, dry_run=True, stdout=False, string=False, transform_percent=True, transform_format=True, transform_concats=True, transform_joins=True, fail_on_change=False, aggressive=False, exclude=None, src=['.dev/bug.py'], version=False)
Running flynt in dry-run mode. No files will be changed.
--- /asdf/qwer/bug.py

+++

@@ -1,2 +1,2 @@

-';'.join(['a', 'b', 'c'])
+";\"\"\".join(['a', 'b', 'c"

fstringifying /asdf/qwer/bug.py...modified

Flynt run has finished. Stats:

Execution time:                            0.003s
Files checked:                             1
Files modified:                            1
Character count reduction:                 25 (96.15%)

Per expression type:
No old style (`%`) expressions attempted.
No `.format(...)` calls attempted.
No concatenations attempted.
Static string joins attempted:             1/1 (100.0%)
F-string expressions created:              1

_-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_.
Please run your tests before committing. Did flynt get a perfect conversion? give it a star at:
~ https://github.com/ikamensh/flynt ~
Thank you for using flynt. Upgrade more projects and recommend it to your colleagues!
```
Python version is 3.11.3
test/test_edits.py::test_joins
test/test_edits.py::test_timestamp test/test_edits.py::test_ifexpr test/test_edits.py::test_binop test/test_edits.py::test_call test/test_edits.py::test_string_specific_len test/test_edits.py::test_dont_wrap_len test/test_edits.py::test_string_in_string_single test/test_edits.py::test_percent_tuple test/test_edits.py::test_part_of_concat test/test_edits.py::test_one_string test/test_edits.py::test_nonatomic test/test_edits.py::test_noqa test/test_edits.py::test_noqa_other test/test_edits.py::test_multiline test/test_edits.py::test_conversion test/test_edits.py::test_invalid_conversion test/test_edits.py::test_invalid_conversion_names test/test_edits.py::test_dangerous_tuple test/test_edits.py::test_percent_newline test/test_edits.py::test_format_newline test/test_edits.py::test_format_tab test/test_edits.py::test_indented test/test_edits.py::test_line_split test/test_edits.py::test_line_split_single_line test/test_edits.py::test_line_split_kw test/test_edits.py::test_openpyxl test/test_edits.py::test_double_percent_2 test/test_edits.py::test_str_in_str test/test_edits.py::test_str_in_str_single_quote test/test_edits.py::test_chain_fmt test/test_edits.py::test_chain_fmt_3 test/test_edits.py::test_empty_line test/test_edits.py::test_dict_perc test/test_edits.py::test_legacy_unicode test/test_edits.py::test_double_percent_no_prob test/test_edits.py::test_percent_dict test/test_edits.py::test_percent_dict_fmt test/test_edits.py::test_double_percent_dict test/test_edits.py::test_percent_dict_reused_key_noop test/test_edits.py::test_percent_dict_reused_key_aggressive test/test_edits.py::test_percent_dict_name test/test_edits.py::test_percent_dict_names test/test_edits.py::test_percent_attr test/test_edits.py::test_percent_dict_prefix test/test_edits.py::test_legacy_fmtspec test/test_edits.py::test_str_in_str_curly test/test_edits.py::test_str_in_str_methods test/test_edits.py::test_decimal_precision test/test_edits.py::test_width_spec test/test_edits.py::test_equiv_expressions_repr test/test_edits.py::test_equiv_expressions_hex test/test_edits.py::test_equiv_expressions_s test/test_edits.py::test_concat test/test_edits.py::test_concat_two_sides test/test_edits.py::test_integers_equivalence[0-e] test/test_edits.py::test_integers_equivalence[0-g] test/test_edits.py::test_integers_equivalence[0-d] test/test_edits.py::test_integers_equivalence[0-i] test/test_edits.py::test_integers_equivalence[0-x] test/test_edits.py::test_integers_equivalence[0-X] test/test_edits.py::test_integers_equivalence[0-u] test/test_edits.py::test_integers_equivalence[11-e] test/test_edits.py::test_integers_equivalence[11-g] test/test_edits.py::test_integers_equivalence[11-d] test/test_edits.py::test_integers_equivalence[11-i] test/test_edits.py::test_integers_equivalence[11-x] test/test_edits.py::test_integers_equivalence[11-X] test/test_edits.py::test_integers_equivalence[11-u] test/test_edits.py::test_integers_equivalence[7-e] test/test_edits.py::test_integers_equivalence[7-g] test/test_edits.py::test_integers_equivalence[7-d] test/test_edits.py::test_integers_equivalence[7-i] test/test_edits.py::test_integers_equivalence[7-x] test/test_edits.py::test_integers_equivalence[7-X] test/test_edits.py::test_integers_equivalence[7-u] test/test_edits.py::test_floats_equivalence[3.33333333-e] test/test_edits.py::test_floats_equivalence[3.33333333-g] test/test_edits.py::test_floats_equivalence[3.33333333-f] test/test_edits.py::test_floats_equivalence[1.5e-43-e] test/test_edits.py::test_floats_equivalence[1.5e-43-g] test/test_edits.py::test_floats_equivalence[1.5e-43-f] test/test_edits.py::test_floats_equivalence[3.142854-e] test/test_edits.py::test_floats_equivalence[3.142854-g] test/test_edits.py::test_floats_equivalence[3.142854-f] test/test_edits.py::test_floats_precision_equiv[3.33333333-.02f] test/test_edits.py::test_floats_precision_equiv[3.33333333-.01e] test/test_edits.py::test_floats_precision_equiv[3.33333333-.04g] test/test_edits.py::test_floats_precision_equiv[3.33333333-05f] test/test_edits.py::test_floats_precision_equiv[1.5e-43-.02f] test/test_edits.py::test_floats_precision_equiv[1.5e-43-.01e] test/test_edits.py::test_floats_precision_equiv[1.5e-43-.04g] test/test_edits.py::test_floats_precision_equiv[1.5e-43-05f] test/test_edits.py::test_floats_precision_equiv[3.142854-.02f] test/test_edits.py::test_floats_precision_equiv[3.142854-.01e] test/test_edits.py::test_floats_precision_equiv[3.142854-.04g] test/test_edits.py::test_floats_precision_equiv[3.142854-05f] test/test_edits.py::test_multiline_tuple test/test_edits.py::test_kv_loop test/test_edits.py::test_unknown_mod_percend_dictionary test/test_edits.py::test_mixed_quote_types test/test_edits.py::test_mixed_quote_types_unsafe test/test_edits.py::test_super_call test/test_edits.py::test_escaped_mix test/test_edits.py::test_escaped_mix_double test/test_edits.py::test_112 test/test_edits.py::test_112_simple test/test_edits.py::test_110 test/test_edits.py::test_110_nonaggr test/test_edits.py::test_literal_direct