Why this story matters before any code
TensorFlow wasn't designed in a vacuum. Inside Google Brain, the predecessor was DistBelief (2011) — the system that trained the famous Google Cat network on YouTube thumbnails. DistBelief was powerful but tightly coupled to internal Google infrastructure, which is why it never escaped Mountain View. TensorFlow's 2015 mandate was explicit: a system that could run on a researcher's laptop and on a Google datacenter without rewriting the model.
Early TensorFlow (1.x) was famous for one thing: graphs first, execution later. You declared a static graph using tf.placeholder and tf.Variable, then opened a tf.Session and called sess.run() with a feed_dict. Debugging meant printing graph nodes, not values. The mental model was so foreign to Python that an entire generation of researchers picked PyTorch instead — and a lot of the ML papers you read in 2024–2026 still default to PyTorch because of that early fork in adoption.
tf.GradientTape, and the @tf.function decorator all exist because Sessions and placeholders were a deal-breaker. Read TF 2.x design choices through this lens and they stop looking arbitrary.
TensorFlow 2.0 (Sept 2019) was a hard reset: eager execution by default, Keras as the official high-level API, @tf.function as the bridge between eager Python and compiled graphs when you need production speed. As of March 2026, the current stable is TensorFlow 2.21.0. Notable in this release: Python 3.9 support is dropped (3.10+ required), TensorBoard ships separately (pip install tensorboard), and TFLite is being extracted into its own LiteRT repository.