<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Vlad Filippov</title>
	<atom:link href="https://vladfilippov.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://vladfilippov.com</link>
	<description>software engineer / web dev / open source hacker</description>
	<lastBuildDate>Wed, 25 Mar 2026 00:56:23 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://vladfilippov.com/wp-content/uploads/2020/04/cropped-vlad-filippov-circle-32x32.png</url>
	<title>Vlad Filippov</title>
	<link>https://vladfilippov.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">137936274</site>	<item>
		<title>Python dependencies with uv</title>
		<link>https://vladfilippov.com/python-dependencies-with-uv/</link>
		
		<dc:creator><![CDATA[Vlad Filippov]]></dc:creator>
		<pubDate>Wed, 25 Mar 2026 00:56:22 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[dependencies]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[uv]]></category>
		<guid isPermaLink="false">https://vladfilippov.com/?p=1649</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[
<span id="more-1649"></span>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img fetchpriority="high" decoding="async" width="977" height="534" src="https://vladfilippov.com/wp-content/uploads/2026/03/py-uv.jpg" alt="Python and uv" class="wp-image-1651" style="aspect-ratio:1.8296293775312256;width:480px;height:auto"/></figure>
</div>


<div class="wp-block-jetpack-markdown"><p>Modern Python dependency management has a clear best-in-class answer for new projects: <strong><a href="https://docs.astral.sh/uv/">uv</a></strong>. It’s fast, it handles your entire toolchain, and it produces <strong>reproducible</strong> environments that behave identically across every developer’s machine, every CI run, and every deployment.</p>
<p>I’ve been looking for something to solve the Python dependency problem for many years and I’m very happy to see <strong>uv</strong> succeed. In this post, I’ve documented the day-to-day workflow for a uv-based project, as well as common operations that uv helps you solve. If you’re maintaining an existing project built around <code>requirements.txt</code>, there’s a section at the end on interoperability.</p>
</div>



<div class="wp-block-jetpack-markdown"><p>A typical Python team used to need:</p>
<ul>
<li><code>pyenv</code> or <code>asdf</code> to manage Python versions</li>
<li><code>virtualenv</code> or <code>venv</code> to create isolated environments</li>
<li><code>pip</code> to install packages</li>
<li><code>pip-tools</code> to compile and lock the full dependency graph</li>
<li><code>pip-audit</code> for security scanning</li>
</ul>
</div>



<div class="wp-block-jetpack-markdown"><p><code>uv</code> replaces all of them with a single tool, written in <strong>Rust</strong>, that runs 10–100x faster than <code>pip</code>. It manages Python installations, creates virtual environments, resolves dependencies, and generates a lockfile — all in one consistent CLI. This eliminates the “works on my machine” class of problems and removes a significant chunk of onboarding friction of Python projects.</p>
</div>



<div class="wp-block-jetpack-markdown"><p>Install it once per machine:</p>
<pre><code class="language-bash"># macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows
powershell -ExecutionPolicy ByPass -c &quot;irm https://astral.sh/uv/install.ps1 | iex&quot;

# Or via pip if you prefer
pip install uv
</code></pre>
</div>



<div class="wp-block-jetpack-markdown"><h2>New project</h2>
<pre><code class="language-bash">uv init my-project
cd my-project
</code></pre>
<p>This creates a minimal project structure:</p>
<pre><code>my-project/
├── .python-version     # Pins the Python version for the project
├── pyproject.toml      # Project metadata and dependencies
├── README.md
└── src/
    └── hello.py
</code></pre>
<p>That’s your starting point. No virtualenv to create manually, no requirements file to bootstrap. The environment gets created automatically the first time you run anything.</p>
</div>



<div class="wp-block-jetpack-markdown"><h3>pyproject.toml</h3>
<p><code>pyproject.toml</code> is the modern standard for Python project configuration (PEP 517/518). You don’t need to understand it deeply to use <code>uv</code>, but knowing the relevant parts helps. Here’s what a typical project looks like after adding a few dependencies:</p>
<pre><code class="language-toml">[project]
name = &quot;my-project&quot;
version = &quot;0.1.0&quot;
requires-python = &quot;&gt;=3.11&quot;
dependencies = [
    &quot;fastapi&gt;=0.110.0&quot;,
    &quot;httpx&gt;=0.27.0&quot;,
    &quot;pydantic&gt;=2.6.0&quot;,
]

[dependency-groups]
dev = [
    &quot;pytest&gt;=8.1.0&quot;,
    &quot;pytest-cov&gt;=5.0.0&quot;,
    &quot;ruff&gt;=0.3.0&quot;,
    &quot;pre-commit&gt;=3.7.0&quot;,
]
</code></pre>
<p>The <code>[project]</code> block declares your direct runtime dependencies — what your application needs to run. The <code>[dependency-groups]</code> block is where environment-specific extras live. <code>dev</code> is the convention for development tools; you can add others like <code>test</code> or <code>lint</code> if your team prefers more granularity.</p>
<p>You generally don’t edit the version pins in <code>pyproject.toml</code> directly. <code>uv</code> manages them for you.</p>
<h3>The Lockfile</h3>
<p>When you add dependencies or run <code>uv sync</code>, <code>uv</code> generates a <code>uv.lock</code> file alongside <code>pyproject.toml</code>. This file pins every package in your entire dependency graph — not just your direct dependencies, but every transitive dependency too. It’s the equivalent of what <code>pip-tools</code> used to produce, but generated automatically.</p>
<p><strong>Commit <code>uv.lock</code> to version control.</strong> This is what guarantees every developer on your team, every CI runner, and every deployment gets byte-for-byte identical environments. Never add it to <code>.gitignore</code>.</p>
<hr>
<h2>Adding and managing dependencies</h2>
<pre><code class="language-bash"># Add a runtime dependency
uv add fastapi

# Add a dev-only dependency
uv add --dev pytest ruff

# Remove a dependency
uv remove httpx

# Upgrade a specific package
uv add fastapi --upgrade

# Upgrade everything
uv lock --upgrade
</code></pre>
<p>Every <code>uv add</code> or <code>uv remove</code> does three things atomically: updates <code>pyproject.toml</code>, re-resolves the full dependency graph, and rewrites <code>uv.lock</code>. You never manually edit version pins, and you never need to remember to run a separate compile step.</p>
<h3>Syncing environments</h3>
<p>When a developer pulls new changes that include <code>uv.lock</code> updates, they run:</p>
<pre><code class="language-bash">uv sync
</code></pre>
<p>This installs or removes packages until the local environment exactly matches the lockfile. It’s idempotent — running it multiple times is safe and fast because <code>uv</code> skips packages that are already at the right version.</p>
<p>For CI and deployment, where you don’t want dev tools installed:</p>
<pre><code class="language-bash"># Install only runtime dependencies, skip dev group
uv sync --no-dev
</code></pre>
<hr>
<h2>Python versions</h2>
<p>One of the less obvious wins from <code>uv</code> is that it handles Python itself. Rather than relying on each developer having the right version installed via <code>pyenv</code> or system packages:</p>
<pre><code class="language-bash"># Install a specific Python version
uv python install 3.12

# Pin the project to a version (writes to .python-version)
uv python pin 3.12
</code></pre>
<p>The <code>.python-version</code> file tells <code>uv</code> which Python to use for this project. Commit it. When a new developer clones the repo and runs <code>uv sync</code>, <code>uv</code> will automatically download and use the pinned Python version — no <code>pyenv</code> required, no “which Python are you using?” debugging.</p>
<hr>
<h2>Commands</h2>
<p><code>uv run</code> is how you execute anything in the project environment. It verifies the environment is in sync with the lockfile before running, so you’re always executing against the correct dependencies:</p>
<pre><code class="language-bash"># Run your application
uv run python src/main.py

# Run tests
uv run pytest

# Run the linter
uv run ruff check .

# Start an interactive shell inside the environment
uv run python
</code></pre>
<p>If you prefer activating the environment directly (for example, in a long interactive session), the virtualenv lives at <code>.venv</code>:</p>
<pre><code class="language-bash">source .venv/bin/activate  # macOS/Linux
.venv\Scripts\activate     # Windows
</code></pre>
<hr>
<h2>Workflow</h2>
<p>For a team, the daily workflow looks like this:</p>
<pre><code class="language-bash"># First time setting up the project
git clone https://github.com/your-org/my-project
cd my-project
uv sync                  # Creates .venv, installs everything from uv.lock

# Adding a new dependency
uv add some-package
git add pyproject.toml uv.lock
git commit -m &quot;Add some-package&quot;

# After pulling changes that include lockfile updates
git pull
uv sync                  # Brings your environment up to date

# Running the test suite
uv run pytest
</code></pre>
<p>The key discipline is simple: always commit both <code>pyproject.toml</code> and <code>uv.lock</code> together when dependencies change. Never commit one without the other.</p>
<h3>Makefile</h3>
<p>A <code>Makefile</code> is still a useful convention for documenting and standardizing how the team interacts with the project:</p>
<pre><code class="language-makefile">.PHONY: install test lint format check

install:
	uv sync

test:
	uv run pytest --cov=src --cov-report=term-missing

lint:
	uv run ruff check .

format:
	uv run ruff format .

check: lint test
</code></pre>
<p>New developers can run <code>make install</code> to get started and <code>make check</code> before opening a PR, without needing to know anything about <code>uv</code>’s internals.</p>
<hr>
<h2>CI/CD integration</h2>
<p><code>uv</code> is well-suited for CI because its global package cache makes repeated installs fast and its lockfile makes environments deterministic. Here’s a GitHub Actions workflow:</p>
<pre><code class="language-yaml"># .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [&quot;3.14&quot;, &quot;3.13&quot;]

    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v5
        with:
          enable-cache: true

      - name: Set up Python ${{ matrix.python-version }}
        run: uv python install ${{ matrix.python-version }}

      - name: Install dependencies
        run: uv sync --frozen --no-dev

      - name: Run tests
        run: uv run pytest --cov=src --cov-report=xml

      - name: Upload coverage
        uses: codecov/codecov-action@v4
</code></pre>
<p>The <code>astral-sh/setup-uv</code> action handles installing <code>uv</code> and wiring up the GitHub Actions cache so downloaded packages are reused across runs. The <code>enable-cache: true</code> option is the key line — it can reduce a cold install from 60 seconds to under 5.</p>
<p>Note <code>--frozen</code> in the install step. This tells <code>uv</code> to use the lockfile exactly as committed and fail loudly if <code>pyproject.toml</code> and <code>uv.lock</code> are out of sync — which would indicate someone forgot to commit the lockfile after adding a dependency. Catching this in CI is much better than catching it in production.</p>
<h2>Security and dependency auditing</h2>
<pre><code class="language-bash"># Check for known CVEs in your dependency tree
uv run pip-audit

# See which packages have newer versions available
uv tree --outdated
</code></pre>
<p><code>pip-audit</code> queries the Python Packaging Advisory Database and flags any installed packages with known vulnerabilities. Adding it to your CI pipeline as a required step ensures nothing with a known CVE ships to production undetected.</p>
<p>For automated updates, Dependabot supports <code>uv</code> lockfiles natively:</p>
<pre><code class="language-yaml"># .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: &quot;uv&quot;
    directory: &quot;/&quot;
    schedule:
      interval: &quot;weekly&quot;
    open-pull-requests-limit: 5
</code></pre>
<p>Dependabot will open pull requests updating individual packages in <code>uv.lock</code>.</p>
<hr>
<h2>Deployment</h2>
<h3>Simple deployment</h3>
<pre><code class="language-bash">git pull origin main
uv sync --frozen --no-dev
sudo systemctl restart myapp
</code></pre>
<p>Because <code>uv sync</code> is driven by the lockfile and idempotent, this is safe to run repeatedly. It only installs or removes what has actually changed. The <code>--frozen</code> flag ensures you never silently re-resolve in production, if the lockfile is somehow stale, the deployment fails fast rather than proceeding with an unverified environment.</p>
<h3>Deployments with a rollback</h3>
<p>For production systems where you need a clean rollback path, install into a staging environment first and only cut over if everything succeeds:</p>
<pre><code class="language-bash">#!/bin/bash
set -e

APP_DIR=&quot;/var/www/myapp&quot;

cd $APP_DIR
git pull origin main

# Sync into a temporary environment
UV_PROJECT_ENVIRONMENT=.venv-next uv sync --frozen --no-dev

# Validate the new environment before cutting over
UV_PROJECT_ENVIRONMENT=.venv-next uv run python -c &quot;import myapp; print('imports OK')&quot;

# Swap environments
mv .venv .venv-prev
mv .venv-next .venv

# Restart
sudo systemctl restart myapp

echo &quot;Deployment successful. Previous env preserved at .venv-prev&quot;
</code></pre>
<hr>
<h2>requirements.txt</h2>
<p>Some tools and older projects still expect a <code>requirements.txt</code>. You can export one from your uv lockfile at any time:</p>
<pre><code class="language-bash"># Export runtime dependencies as a pinned requirements.txt
uv export --no-dev --output-file requirements.txt

# Export including dev dependencies
uv export --output-file requirements-dev.txt
</code></pre>
<p>The exported file is fully pinned with hashes, suitable for any standard pip workflow. The important thing is that <code>requirements.txt</code> becomes a <em>build artifact</em> in this workflow, not a source of truth. Keep <code>pyproject.toml</code> and <code>uv.lock</code> as the canonical source and regenerate the export as needed — ideally as a CI step so it’s always current.</p>
<p>If you’re migrating an existing project from <code>requirements.txt</code> to <code>uv</code>:</p>
<pre><code class="language-bash">uv init --no-readme
uv add -r requirements.txt
uv add --dev -r requirements-dev.txt
</code></pre>
<hr>
<h2>Summary</h2>
<ol>
<li><strong><code>uv</code> replaces your whole toolchain</strong> — pip, virtualenv, pyenv, and pip-tools in one install</li>
<li><strong>Commit <code>uv.lock</code></strong> — this is what makes environments identical across your team and CI</li>
<li><strong>Use dependency groups</strong> to separate runtime and dev dependencies in <code>pyproject.toml</code></li>
<li><strong>Use <code>uv run</code> for everything</strong> — it keeps environments in sync automatically</li>
<li><strong>Use <code>--frozen</code> in CI and production</strong> — fail fast if the lockfile is stale, never silently re-resolve</li>
<li><strong>Automate security audits</strong> with <code>pip-audit</code> in CI and Dependabot for weekly updates</li>
<li><strong>Export <code>requirements.txt</code> only when needed</strong> for interop, as a build artifact</li>
</ol>
<p>With this workflow every developer gets the same environment, CI catches what local development misses, and deployments don’t surprise you. <code>uv</code> makes that easier to achieve than anything else in the Python ecosystem right now.</p>
<p><em>Have questions about Python dependencies or deployment workflows? Connect with me on <a href="https://github.com/vladikoff">GitHub</a> or <a href="https://linkedin.com/in/vladikoff">LinkedIn</a>.</em></p>
</div>



<p></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1649</post-id>	</item>
		<item>
		<title>playwright-ai CLI tool</title>
		<link>https://vladfilippov.com/playwright-ai/</link>
		
		<dc:creator><![CDATA[Vlad Filippov]]></dc:creator>
		<pubDate>Fri, 08 Dec 2023 04:02:15 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://vladfilippov.com/?p=1502</guid>

					<description><![CDATA[Recently open-sourced the playwright-ai project &#8211; a tool to generate LLM-based Playwright functional tests. Try it out via the docs...]]></description>
										<content:encoded><![CDATA[
<span id="more-1502"></span>



<p>Recently open-sourced the playwright-ai project &#8211; a tool to generate LLM-based Playwright functional tests. Try it out via the docs at: <a href="https://github.com/vladikoff/playwright-ai">https://github.com/vladikoff/playwright-ai</a></p>



<figure class="wp-block-video"><video height="1080" style="aspect-ratio: 1080 / 1080;" width="1080" controls muted src="https://vladfilippov.com/wp-content/uploads/2023/12/pai-t.mp4"></video></figure>



<p>Still early, but it is useful for web projects that have zero functional tests! It has some fun stuff like support for OpenAI and Anthropic models in the CLI and self-healing tests through re-prompting. Hopefully more features soon…</p>



<p>Supported models:</p>



<ul class="wp-block-list">
<li>Anthropic&#8217;s Claude &#8211; configure API key with&nbsp;an <code>ANTHROPIC_API_KEY</code>.</li>



<li>OpenAI&#8217;s GPT3 and GPT4 &#8211; configure API key with&nbsp;an <code>OPENAI_API_KEY</code>.</li>
</ul>



<h2 class="wp-block-heading"><a href="https://github.com/vladikoff/playwright-ai#quick-start"></a>Quick start</h2>



<ul class="wp-block-list">
<li>Make sure you have the most basic Playwright installation with&nbsp;<code>npm init playwright@latest</code>. See&nbsp;<a href="https://playwright.dev/docs/intro#installing-playwright">https://playwright.dev/docs/intro#installing-playwright</a>&nbsp;for details.</li>



<li>Install the CLI:</li>
</ul>



<pre class="wp-block-code"><code>npm -g playwright-ai
</code></pre>



<ul class="wp-block-list">
<li>Obtrain the API key for the LLM model of your choice:&nbsp;<a href="https://www.anthropic.com/">Anthropic</a>&nbsp;or&nbsp;<a href="https://openai.com/">OpenAI</a>.</li>



<li>Execute the CLI from project directory:</li>
</ul>



<pre class="wp-block-code"><code>playwright-ai --endpoint=https://example.com --model=claude --tests=1
</code></pre>



<ul class="wp-block-list">
<li>After the CLI is done, it will generate the tests into the Playwright test directory. As the tests generate, the CLI will have both passing and failing tests. The failing tests will have to be manually fixed by the user of the tool.</li>
</ul>



<figure class="wp-block-image"><a href="https://github.com/vladikoff/playwright-ai/blob/main/assets/pw-demo.gif" target="_blank" rel="noreferrer noopener"><img decoding="async" src="https://github.com/vladikoff/playwright-ai/raw/main/assets/pw-demo.gif" alt="playwright-ai demo"/></a></figure>



<p>I suggested using either the GPT-4 or Claude 2 models to get better results. Try out the tool in your own projects and let me know if it generated useful tests! </p>
]]></content:encoded>
					
		
		<enclosure url="https://vladfilippov.com/wp-content/uploads/2023/12/pai-t.mp4" length="6395083" type="video/mp4" />

		<post-id xmlns="com-wordpress:feed-additions:1">1502</post-id>	</item>
		<item>
		<title>A New Book on JavaScript Frameworks</title>
		<link>https://vladfilippov.com/new-book-on-javascript-frameworks/</link>
		
		<dc:creator><![CDATA[Vlad Filippov]]></dc:creator>
		<pubDate>Fri, 27 Oct 2023 04:03:00 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://vladfilippov.com/?p=1493</guid>

					<description><![CDATA[For JavaScript developers of all levels, my new book &#8220;Building Your Own JavaScript Framework&#8221; offers valuable insights into the world...]]></description>
										<content:encoded><![CDATA[
<span id="more-1493"></span>



<p>For JavaScript developers of all levels, my new book &#8220;Building Your Own JavaScript Framework&#8221; offers valuable insights into the world of all sorts of JavaScript frameworks. Whether you&#8217;re new to the scene or a seasoned expert, understanding how frameworks function under the hood will refine your skills and perspective.</p>



<p>In this book, we&#8217;ll explore the dynamic history of JavaScript frameworks, fueled by an innovative community pushing the boundaries of web development on both the front-end, back-end, and in other spaces. We&#8217;ll look at how each new framework brings a unique philosophy and solution set to common challenges.</p>



<figure class="wp-block-video"><video height="1080" style="aspect-ratio: 1080 / 1080;" width="1080" controls src="https://vladfilippov.com/wp-content/uploads/2023/10/book-final.m4v"></video></figure>



<p>Our goal extends beyond simply creating a framework from scratch. This book aims to deepen your comprehension of reusable architectures and encourage thinking from a framework point of view. With this improved understanding, you&#8217;ll be equipped to craft, maintain, and advance your own frameworks.</p>



<p>The book starts by introducing the JavaScript framework landscape. We&#8217;ll guide you through building your own framework, highlighting best practices along the way. To fully benefit, you should have a solid grasp of JavaScript and some experience with existing frameworks. Whether you&#8217;re a JavaScript expert or just starting out, this book will provide new depths of insight.</p>



<p>Key Features:</p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f31f.png" alt="🌟" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Explore the gateway to the constantly evolving world of JavaScript frameworks. </p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Navigate the JavaScript development landscape and master crucial software architecture patterns.</p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Your ultimate guide to building your own framework for career-related projects and beyond!</p>



<p>Check out the <a href="https://vladfilippov.com/frameworks/"><strong>publication page</strong></a> for more information.</p>
]]></content:encoded>
					
		
		<enclosure url="https://vladfilippov.com/wp-content/uploads/2023/10/book-final.m4v" length="9441936" type="video/mp4" />

		<post-id xmlns="com-wordpress:feed-additions:1">1493</post-id>	</item>
		<item>
		<title>Speaking at Refactor DX 2023</title>
		<link>https://vladfilippov.com/refactor-dx-2023/</link>
		
		<dc:creator><![CDATA[Vlad Filippov]]></dc:creator>
		<pubDate>Sun, 16 Jul 2023 02:31:00 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://vladfilippov.com/?p=1450</guid>

					<description><![CDATA[I got the honour of speaking at the Refactor DX 2023 conference in my hometown &#8211; Toronto. This was a...]]></description>
										<content:encoded><![CDATA[
<span id="more-1450"></span>



<p>I got the honour of speaking at the Refactor DX 2023 conference in my hometown &#8211; Toronto. This was a great opportunity for me to share my knowledge and insights on end-to-end testing for modern web applications.</p>



<figure class="wp-block-image size-large is-resized"><a href="https://vladfilippov.com/wp-content/uploads/2023/09/IMG_3525.jpeg"><img decoding="async" src="https://vladfilippov.com/wp-content/uploads/2023/09/IMG_3525-1024x768.jpeg" alt="" class="wp-image-1452" style="width:759px;height:569px" width="759" height="569"/></a></figure>



<p>My talk was titled &#8220;The State of End-to-End Testing for modern web applications.&#8221; In this session, I discussed how the landscape for end-to-end testing has evolved since 2004. Back then, testing complex web apps end-to-end was painfully difficult and time-consuming. But today, thanks to modern testing frameworks and cloud services, it&#8217;s much easier to thoroughly test front-end, back-end, APIs, and everything in between.</p>



<p>You can watch the recorded version of my talk below:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe class="youtube-player" width="700" height="394" src="https://www.youtube.com/embed/0ppFqmRiGQw?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-US&#038;autohide=2&#038;wmode=transparent" allowfullscreen="true" style="border:0;" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox"></iframe>
</div></figure>



<p>During my talk, I outlined some of the main challenges we used to face when doing end-to-end testing:</p>



<ul class="wp-block-list">
<li>Setting up and maintaining our own testing environments</li>



<li>Dealing with flaky tests and false failures</li>



<li>Writing and maintaining tons of complex test code</li>



<li>Slow and unreliable feedback loops</li>
</ul>



<p>I then showcased some of the tools and techniques we can leverage today to overcome these challenges. With the addition of showing how testing tools will be much more improved by adding AI and LLM assistance into the mix. The audience was very engaged during the talk and asked some thoughtful questions afterward. It was clear many of them had experienced the testing pains I referenced from early in my career. Overall, I found Refactor DX 2023 to be exceptional, here are some of my main takeaways:</p>



<ul class="wp-block-list">
<li>Testing is more important than ever as web apps become more complex. We can&#8217;t skimp on end-to-end testing.</li>



<li>There are fantastic open source tools available today that make testing much easier and faster than before. Taking time to learn them is worth the investment.</li>



<li>Good testing requires strategic thinking, not just tools. Set your team up for testing success by instilling the right culture and values around quality.</li>
</ul>



<p>I&#8217;m so glad I had the chance to present at Refactor DX this year. Conferences like this are such a great way to both share knowledge and stay on top of the latest industry trends. Looking forward to what the Refactor community will be up to in the coming months! If you are looking to follow along, join the community on LinkedIn: <a href="https://www.linkedin.com/company/refactor-community">https://www.linkedin.com/company/refactor-community</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1450</post-id>	</item>
		<item>
		<title>At Test Automation Summit 2023</title>
		<link>https://vladfilippov.com/at-test-automation-summit-2023/</link>
		
		<dc:creator><![CDATA[Vlad Filippov]]></dc:creator>
		<pubDate>Mon, 29 May 2023 00:03:38 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Talks]]></category>
		<guid isPermaLink="false">https://vladfilippov.com/?p=1419</guid>

					<description><![CDATA[Recently, I had the honour of speaking at the Test Automation &#38; Digital QA Summit (TAS23) in Toronto, a renowned...]]></description>
										<content:encoded><![CDATA[
<span id="more-1419"></span>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://vladfilippov.com/wp-content/uploads/2023/05/tas23x-1.jpeg"><img loading="lazy" decoding="async" width="552" height="337" src="https://vladfilippov.com/wp-content/uploads/2023/05/tas23x-1.jpeg" alt="" class="wp-image-1425"/></a></figure>
</div>


<p>Recently, I had the honour of speaking at the Test Automation &amp; Digital QA Summit (TAS23) in Toronto, a renowned global event attracting the brightest minds in software testing, test automation, and digital quality assurance. This summit is an invaluable gathering for Quality Assurance (QA) enthusiasts, which is hosted annually across twelve countries worldwide.</p>



<p>My talk, titled &#8220;Testing and Automation of Web Applications&#8221;, delved into the fascinating world of web browser automation testing. Over the years, this realm has seen significant evolution, triggered by innovative browser engines and cutting-edge tools. A focal point of my presentation was on how reliable cross-browser testing has become indispensable in today&#8217;s QA workflows, playing a crucial role in many projects. The power of integrating such testing within continuous integration pipelines cannot be overstated—it leads to superior quality products, faster release cycles, and an enhanced developer experience.</p>


<div class="wp-block-image">
<figure class="aligncenter size-medium"><a href="https://vladfilippov.com/wp-content/uploads/2023/05/tasphotos.jpeg"><img loading="lazy" decoding="async" width="300" height="300" src="https://vladfilippov.com/wp-content/uploads/2023/05/tasphotos-300x300.jpeg" alt="" class="wp-image-1423"/></a></figure>
</div>


<p>One of the principal takeaways from the talk was understanding the practical experiences and challenges that come with automating web applications. This process involves managing the complexity of supporting a diverse range of web browsers and grappling with different authentication flows, among other things. I highlighted how tools like Playwright are transforming the landscape of web automation tooling and shared in-depth examples of their optimal configuration.</p>



<p>This talk was designed to be a comprehensive introduction to the topic, loaded with practical examples to help attendees understand how they can implement similar automation strategies in their projects. A key objective was to help the audience recognize that with the right tools and strategies, web application automation can help achieve substantial improvements in product quality and operational efficiency.</p>



<p>Remember, the world of testing and automation is ever-evolving!</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1419</post-id>	</item>
		<item>
		<title>New patterns for amazing apps</title>
		<link>https://vladfilippov.com/new-patterns-for-amazing-apps/</link>
		
		<dc:creator><![CDATA[Vlad Filippov]]></dc:creator>
		<pubDate>Mon, 10 Oct 2022 20:20:25 +0000</pubDate>
				<category><![CDATA[Links]]></category>
		<guid isPermaLink="false">https://vladfilippov.com/?p=1401</guid>

					<description><![CDATA[https://web.dev/new-patterns-for-amazing-apps/]]></description>
										<content:encoded><![CDATA[
<p><a href="https://web.dev/new-patterns-for-amazing-apps/">https://web.dev/new-patterns-for-amazing-apps/</a></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1401</post-id>	</item>
		<item>
		<title>Working with Python Pandas</title>
		<link>https://vladfilippov.com/working-with-python-pandas/</link>
		
		<dc:creator><![CDATA[Vlad Filippov]]></dc:creator>
		<pubDate>Tue, 21 Dec 2021 21:35:28 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://vladfilippov.com/?p=1302</guid>

					<description><![CDATA[Python Pandas, the data analysis library has very good documentation, including both the API reference and the user guide. I...]]></description>
										<content:encoded><![CDATA[
<span id="more-1302"></span>



<p>Python <a rel="noreferrer noopener" href="https://pandas.pydata.org/" target="_blank">Pandas</a>, the data analysis library has very good documentation, including both the <a rel="noreferrer noopener" href="https://pandas.pydata.org/docs/reference/index.html#api" target="_blank">API reference</a> and the <a rel="noreferrer noopener" href="https://pandas.pydata.org/docs/user_guide/index.html#user-guide" target="_blank">user guide</a>. I like how descriptive it is and the clean design of the docs site makes it very readable. However, I do find that it still takes a bit of time to get started with Pandas, even if you have years and years of Python programming experience.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>This article has been updated in March 2026 </strong>to include the latest changes with the Pandas 3.0 release. There are some significant improvements worth knowing about, including better performance with Arrow backends and the new Copy-on-Write default behaviour that eliminates those annoying <em>SettingWithCopyWarning</em> messages.</p>
</blockquote>
</blockquote>



<p>Getting started, install the module. This could be an obvious step, but anyway:</p>



<pre class="wp-block-code"><code><em># Install with performance improvements</em>
pip install pandas&#91;all]
<em># or the basic version</em>
pip install pandas

<em># in a new or existing .py file, import the module and make sure it works</em>
import pandas as pd</code></pre>



<p>Pandas is able to load CSV and SQL files, you can use <a href="https://pandas.pydata.org/docs/reference/api/pandas.read_csv.html#pandas.read_csv">.read_csv()</a> for that. In this article, we create a DataFrame &#8220;inline&#8221; to focus on the rest of the Pandas API. We can create an example frame like this:</p>



<pre class="wp-block-code"><code>data = pd.DataFrame({
    "name": &#91;"Tim", "Roger", "Bob", "Sarah", "Mike"],
    "town": &#91;"Toronto", "Ottawa", "London", "Montreal", "Vancouver"],
    "balance": &#91;50000, 52000, None, 65000, 48000],
    "account_type": &#91;"Savings", "Checking", "Savings", "Investment", "Checking"],
})</code></pre>



<p>Printing this out with <code>print(data)</code> will produce a nice table for you:</p>



<pre class="wp-block-code"><code>    name       town   balance account_type
0    Tim    Toronto   50000.0      Savings
1  Roger     Ottawa   52000.0     Checking
2    Bob     London       NaN      Savings
3  Sarah   Montreal   65000.0   Investment
4   Mike  Vancouver   48000.0     Checking</code></pre>



<p>Now that we have our sample data all setup, I want to go over some of the common and crucial Pandas operations that will help you become a Pandas expert. These should also help you understand how the library works and what it is capable of. I&#8217;ve also included some modern patterns that have become popular in 2026.</p>



<h3 class="wp-block-heading">Finding items by index</h3>



<pre class="wp-block-code"><code># Setup an "index" on name. Now we can use ".loc" to find things
data.set_index('name', inplace=True)

# Look up item by name "Tim" using the index
print(data.loc&#91;"Tim", :])

# Look up items by ".iloc", the "index" location.
print(data.iloc&#91;0, :])

# Modern approach: using query() for readable filtering
toronto_accounts = data.query('town == "Toronto"')
print(toronto_accounts)</code></pre>



<h3 class="wp-block-heading"><meta charset="utf-8">Rewriting column names</h3>



<pre class="wp-block-code"><code># The following updates the columns in our data frame.
cols = list(data.columns)
cols&#91;0] = 'Location'
cols&#91;1] = 'Balance' 
cols&#91;2] = 'AccountType'
data.columns = cols

# Modern alternative using rename() method
data = data.rename(columns={
    'town': 'Location',
    'balance': 'Balance',
    'account_type': 'AccountType'
})</code></pre>



<h3 class="wp-block-heading">Get the number of rows and columns</h3>



<pre class="wp-block-code"><code># returns a tuple pair, which are number of rows and cols in the data
data.shape

# Get more detailed info about your DataFrame
data.info()</code></pre>



<h3 class="wp-block-heading">Ranges</h3>



<pre class="wp-block-code"><code># Looking up first and last rows
data.head(1)
data.tail(1)

# Using "list" lookup, other list range options work here as well
data&#91;1:]

# Get specific rows by position
data.iloc&#91;1:3]  # rows 1 and 2
</code></pre>



<h3 class="wp-block-heading">Data types</h3>



<pre class="wp-block-code"><code># query the data type
data.dtypes

# Location     object
# Balance     float64
# AccountType  object
# dtype: object

# Modern approach: optimize data types for better performance
data&#91;'Balance'] = pd.to_numeric(data&#91;'Balance'], errors='coerce')
data&#91;'AccountType'] = data&#91;'AccountType'].astype('category')  # saves memory
data&#91;'Location'] = data&#91;'Location'].astype('string')  # new string dtype in pandas 3.0

</code></pre>



<h3 class="wp-block-heading">Query the data</h3>



<pre class="wp-block-code"><code># look up the data based on columns
data&#91;&#91;'Location', 'Balance']]

# Get all the positive balances
print(data&#91;data&#91;'Balance'] > 0])

# You can also use the query syntax for this (recommended for readability)
print(data.query('Balance > 0'))

# Query with string columns
toronto_accounts = data.query('Location == "Toronto"')
high_balance = data.query('Balance > 50000')</code></pre>



<h3 class="wp-block-heading">Conditional Lookup</h3>



<pre class="wp-block-code"><code># an AND statement
print(data&#91;(data&#91;'Balance'] > 50000) &amp; (data&#91;'Location'] == 'Toronto')])

# an OR statement  
print(data&#91;(data&#91;'Balance'] > 55000) | (data&#91;'Location'] == 'Vancouver')])

# Modern query syntax (more readable)
print(data.query('Balance > 50000 and Location == "Toronto"'))
print(data.query('Balance > 55000 or Location == "Vancouver"'))</code></pre>



<h3 class="wp-block-heading">Sorting</h3>



<pre class="wp-block-code"><code># sorts the data
data.sort_values(by='Balance', ascending=False)

# Multiple column sorting
data.sort_values(&#91;'Location', 'Balance'], ascending=&#91;True, False])</code></pre>



<p>For more advanced sorting methods, check out this article: <a rel="noreferrer noopener" href="https://realpython.com/pandas-sort-python/" data-type="URL" data-id="https://realpython.com/pandas-sort-python/" target="_blank">Pandas Sort: Your Guide to Sorting Data in Python</a>.</p>



<h2 class="wp-block-heading">Modern Method Chaining (New in 2026)</h2>



<p>One of the most powerful patterns that has become popular is method chaining, which lets you write more readable data pipelines:</p>



<pre class="wp-block-code"><code><em># Instead of multiple assignment statements, chain operations together</em>
result = (data
    .query('Balance &gt; 40000')  <em># Filter accounts with balance &gt; 40k</em>
    .assign(
        BalanceCategory=lambda x: pd.cut(x&#91;'Balance'], 
                                        bins=&#91;0, 50000, 60000, float('inf')], 
                                        labels=&#91;'Standard', 'Premium', 'Elite'])
    )
    .groupby(&#91;'Location', 'BalanceCategory'])
    .agg({'Balance': &#91;'count', 'mean']})
    .round(2)
)</code></pre>



<h2 class="wp-block-heading">Working with Missing Data</h2>



<pre class="wp-block-code"><code><em># Check for missing values</em>
print(data.isna().sum())

<em># Fill missing values</em>
data&#91;'Balance'].fillna(data&#91;'Balance'].median(), inplace=True)

<em># Or use method chaining approach</em>
clean_data = (data
    .assign(Balance=lambda x: x&#91;'Balance'].fillna(x&#91;'Balance'].median()))
    .dropna()  <em># remove any remaining missing values</em>
)</code></pre>



<h2 class="wp-block-heading">Grouping and Aggregation</h2>



<pre class="wp-block-code"><code><em># Group by location and get summary stats</em>
location_summary = data.groupby('Location').agg({
    'Balance': &#91;'count', 'mean', 'sum'],
    'AccountType': lambda x: x.mode().iloc&#91;0] if not x.empty else 'Unknown'
}).round(2)

<em># Custom aggregation functions</em>
def balance_range(series):
    return series.max() - series.min()

custom_stats = data.groupby('Location').agg(
    avg_balance=('Balance', 'mean'),
    total_accounts=('Balance', 'count'),
    balance_spread=('Balance', balance_range)
)

</code></pre>



<h2 class="wp-block-heading">Performance Tips for 2026</h2>



<pre class="wp-block-code"><code><em># Use proper data types for better performance</em>
optimized_data = pd.DataFrame({
    "name": pd.array(&#91;"Tim", "Roger", "Bob"], dtype="string"),  <em># Arrow-backed strings</em>
    "town": pd.Categorical(&#91;"Toronto", "Ottawa", "London"]),  <em># Categories for repeated values</em>
    "balance": pd.array(&#91;50000, 52000, 48000], dtype="Int64"),  <em># Nullable integers</em>
})

<em># For large datasets, use eval() for complex calculations</em>
<em># This is much faster than regular operations on big DataFrames</em>
large_data = pd.DataFrame({
    'revenue': np.random.randint(1000, 10000, 100000),
    'costs': np.random.randint(500, 8000, 100000),
    'tax_rate': 0.13  <em># Ontario HST rate</em>
})

<em># Fast calculation using eval</em>
large_data = large_data.eval('profit = revenue - costs')
large_data = large_data.eval('after_tax_profit = profit * (1 - tax_rate)')</code></pre>



<h3 class="wp-block-heading">Save to CSV file</h3>



<pre class="wp-block-code"><code># Saves the data into a file
data.to_csv('canadian_accounts.csv', index=False)

# Modern alternatives for better performance
data.to_parquet('canadian_accounts.parquet')  # Much faster for large files

# Excel with multiple sheets
with pd.ExcelWriter('bank_report.xlsx') as writer:
    data.to_excel(writer, sheet_name='Account_Data', index=False)
    location_summary.to_excel(writer, sheet_name='Location_Summary')</code></pre>



<h2 class="wp-block-heading">Reading Data with Modern Options</h2>



<pre class="wp-block-code"><code><em># Read CSV with optimized settings</em>
df = pd.read_csv('canadian_accounts.csv', 
                dtype_backend='pyarrow',  <em># Use Arrow backend for performance</em>
                parse_dates=&#91;'date_column'] if 'date_column' in data.columns else None)

<em># Read Parquet (recommended for large datasets)</em>
df = pd.read_parquet('canadian_accounts.parquet')
</code></pre>



<h2 class="wp-block-heading">Error Handling and Debugging</h2>



<pre class="wp-block-code"><code><em># Debug your data pipelines with helper functions</em>
def debug_dataframe(df, step_name=""):
    print(f"{step_name}: {df.shape} rows, {df.columns.tolist()}")
    return df

<em># Use in method chains</em>
result = (data
    .pipe(debug_dataframe, "Start")
    .query('Balance &gt; 45000')
    .pipe(debug_dataframe, "After filtering") 
    .groupby('Location')&#91;'Balance'].mean()
    .pipe(debug_dataframe, "Final result")
)</code></pre>



<p>As recommended by the official Pandas website, the <a rel="noreferrer noopener" href="https://www.amazon.com/gp/product/1491957662" target="_blank">Python for Data Analysis: Data Wrangling with Pandas, NumPy, and IPython</a> book can also be very useful if you are looking to learn more about Python data analysis. I hope these syntax examples saved you some time learning the Pandas library :).</p>



<p>The major improvements in Pandas 3.0 make it significantly faster and more memory-efficient than previous versions, especially when working with string data and large datasets. The <a href="https://pandas.pydata.org/docs/development/copy_on_write.html">Copy-on-Write </a>behavior also means you don&#8217;t have to worry about those confusing warning messages anymore.</p>



<p></p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1302</post-id>	</item>
		<item>
		<title>Tech Workshops with TechXplore</title>
		<link>https://vladfilippov.com/workshops-with-techxplore/</link>
		
		<dc:creator><![CDATA[Vlad Filippov]]></dc:creator>
		<pubDate>Tue, 26 Oct 2021 23:47:00 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://vladfilippov.com/?p=1301</guid>

					<description><![CDATA[Just last week, I presented a workshop on web technologies with TechExplore, it&#8217;s been a great mentoring experience to showcase...]]></description>
										<content:encoded><![CDATA[
<span id="more-1301"></span>



<p>Just last week, I presented a workshop on web technologies with TechExplore, it&#8217;s been a great mentoring experience to showcase the Web tech to undergraduate students from different fields. Co-presented with General Assembly Toronto, we&#8217;ve setup 2 workshops &#8211; one about the Web (CSS, HTML &amp; JavaScript) and the second one about programming with Python. The goal is to inspire more minds to get into the technology fields in some capacity. A bit about <strong><a rel="noreferrer noopener" href="https://www.ulife.utoronto.ca/organizations/view/id/120413" target="_blank">TechXplore</a></strong>: </p>



<figure class="wp-block-pullquote"><blockquote><p>TechXplore aims to teach programming and advanced technology skills to our University of Toronto peers in a fun and hands-on environment. Through our workshops, speaker series, and annual hackathon HackXplore, we empower our fellow UofT students from all faculties and colleges. We provide the technology tools, industry connections and trends to help students succeed in their future career and studies.</p><cite>https://www.ulife.utoronto.ca/organizations/view/id/120413</cite></blockquote></figure>



<p>The second workshop that I will be hosting is the <strong>Intro to Python</strong> presentation with TechExplore on October 26. Registration is still open at <a rel="noreferrer noopener" href="https://www.techxplore-uoft.com/event" target="_blank">https://www.techxplore-uoft.com/event</a>. If you are a university student or someone outside of the technology field you may find these workshops useful to expand your skills and find new opportunities. </p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1301</post-id>	</item>
		<item>
		<title>At SmashingConf Live</title>
		<link>https://vladfilippov.com/at-smashingconf-live/</link>
		
		<dc:creator><![CDATA[Vlad Filippov]]></dc:creator>
		<pubDate>Thu, 20 Aug 2020 18:04:10 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://vladfilippov.com/?p=1217</guid>

					<description><![CDATA[Here are some notes and slides from my SmashingConf Live talk from August 2020! Meet&#160;SmashingConf Live&#160;(August 20–21), a truly&#160;smashing, friendly&#160;online&#160;conference...]]></description>
										<content:encoded><![CDATA[
<p>Here are some notes and slides from my <a rel="noreferrer noopener" href="https://smashingconf.com/live/" target="_blank">SmashingConf Live</a> talk from August 2020! </p>



<span id="more-1217"></span>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Meet&nbsp;<strong>SmashingConf Live</strong>&nbsp;(August 20–21), a truly&nbsp;<em>smashing</em>, friendly&nbsp;<strong>online</strong>&nbsp;conference on&nbsp;<strong>front-end &amp; UX</strong>. With interactive&nbsp;<strong>live sessions</strong>, practical insights, accessible speakers, collaborative notes and fireplace chats with like-minded folks.</p></blockquote>



<p>The importance of WebAssembly in front-end development is growing and who knows where this technology will go next! Just over 8 months ago Web Assembly / WASM became an official Web Standard. This standard is a new frontier for front-end development that enables new possibilities to build more advanced projects, speed up their applications and learn new concepts. Even though fairly new,&nbsp;<strong>WebAssembly</strong>&nbsp;is already here in tools, libraries and large web applications.</p>



<p>There are many ways to get started with WebAssembly. In my technical session I went through a way to add WASM to existing projects. I also focused on helping attendees make the choice and evaluate if and where WASM would be successful in their dev life, especially for front-end web developers. </p>



<p>I&#8217;d like to thank the SmashingConf for organizing such an interactive event, with music, live chatter, Q&amp;As and more, especially with the challenges of moving it to a remote conference. </p>



<p>Some useful resources and links from my talk:</p>



<ul class="wp-block-list"><li>WebAssembly becomes a W3C Recommendation: <a rel="noreferrer noopener" href="https://www.w3.org/2019/12/pressrelease-wasm-rec.html.en" target="_blank">https://www.w3.org/2019/12/pressrelease-wasm-rec.html.en</a></li><li>“New Kid on the Web: A Study on the Prevalence of WebAssembly in the Wild” <a href="https://www.sec.cs.tu-bs.de/pubs/2019a-dimva.pdf">https://www.sec.cs.tu-bs.de/pubs/2019a-dimva.pdf</a></li><li>WebAssembly at eBay: A Real-World Use Case <a href="https://tech.ebayinc.com/engineering/webassembly-at-ebay-a-real-world-use-case/">https://tech.ebayinc.com/engineering/webassembly-at-ebay-a-real-world-use-case/</a></li><li>Create Tableau-like data visualizations in browser, powered by WebAssembly <a href="https://muzejs.org/">https://muzejs.org/</a></li><li>Streaming Analytics&nbsp;<em>via</em>&nbsp;WebAssembly <a href="https://perspective.finos.org/">https://perspective.finos.org/</a></li><li>WebAssembly <a href="https://webassembly.studio/">https://webassembly.studio/</a></li><li>Awesome WebAssembly Languages <a href="https://github.com/appcypher/awesome-wasm-langs">https://github.com/appcypher/awesome-wasm-langs</a></li><li>WebAssembly threads <a href="https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format#WebAssembly_threads">https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format#WebAssembly_threads</a></li><li><a href="https://cggallant.blogspot.com/2020/07/webassembly-threads-in-firefox.html">WebAssembly threads in Firefox</a></li><li>Bytecode Alliance <a href="https://bytecodealliance.org/">https://bytecodealliance.org/</a></li><li><a href="https://towardsdatascience.com/why-would-you-use-webassembly-to-put-scikit-learn-in-the-browser-77671e8718d6">Why would you use WebAssembly to put scikit-learn in the browser?</a></li><li><a href="https://www.smashingmagazine.com/2019/04/webassembly-speed-web-app/">How We Used WebAssembly To Speed Up Our Web App By 20X (Case Study)</a></li><li><a href="https://www.figma.com/blog/webassembly-cut-figmas-load-time-by-3x/">WebAssembly cut Figma&#8217;s load time by 3x</a></li><li><a href="https://blogs.autodesk.com/autocad/autocad-web-app-google-io-2018/">The AutoCAD Web App</a></li><li><a href="https://twitter.com/WasmWeekly">twitter.com/WasmWeekly</a></li></ul>



<p>and finally the slides below:</p>



<iframe loading="lazy" src="https://docs.google.com/presentation/d/e/2PACX-1vTpoz8eKw15V3eVrzqwVsgCVJv1d216BBv70lNP89ma8Zv_52XYAr_TCSEiXj9P9yY1hP_2NsAILuhh/embed?start=false&amp;loop=false&amp;delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>



<p>Please reach out to me via my contact page or on Twitter if you have any questions about my talk!</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1217</post-id>	</item>
		<item>
		<title>Favourite 3D prints &#8211; Summer 2020</title>
		<link>https://vladfilippov.com/favourite-3d-prints-summer-2020/</link>
		
		<dc:creator><![CDATA[Vlad Filippov]]></dc:creator>
		<pubDate>Fri, 17 Jul 2020 01:26:58 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<guid isPermaLink="false">https://vladfilippov.com/?p=1189</guid>

					<description><![CDATA[I wanted to create a quick list of my favourite 3D prints for the summer of 2020. Hopefully this gives...]]></description>
										<content:encoded><![CDATA[
<span id="more-1189"></span>



<p>I wanted to create a quick list of my favourite 3D prints for the <strong>summer of 2020</strong>. Hopefully this gives someone ideas for their new 3D print and highlights some of these cool models out there! </p>



<h3 class="wp-block-heading">Gear Bearing</h3>



<p><a href="https://www.thingiverse.com/thing:53451">https://www.thingiverse.com/thing:53451</a></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="250" height="234" src="https://vladfilippov.com/wp-content/uploads/2020/07/gear3.gif" alt="" class="wp-image-1190"/></figure>



<p>A quick printed Gear Bearing is a fascinating model. It makes a cool sound while spinning and is all printed in place. By this time this model is a classic!</p>



<h3 class="wp-block-heading">3D Benchy</h3>



<p><a href="https://www.thingiverse.com/thing:763622">https://www.thingiverse.com/thing:763622</a></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="206" height="251" src="https://vladfilippov.com/wp-content/uploads/2020/07/image.png" alt="" class="wp-image-1193"/></figure>



<p>Must include the 3D Benchy in this first list. It&#8217;s a great looking print and used for benchmarking. You may notice that one of the benches looks horrible, it did not print well at first.</p>



<h3 class="wp-block-heading">Trivenger Boomerang</h3>



<p><a href="https://www.prusaprinters.org/prints/15353-trivenger-boomerang">https://www.prusaprinters.org/prints/15353-trivenger-boomerang</a></p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://vladfilippov.com/wp-content/uploads/2020/07/boomera.jpg" alt="" class="wp-image-1196" width="414" height="371"/></figure>



<p>I printed a few of these, the photo above is the first version. It turned out a bit rough, but it still flies! This is one of my favourite models so far.</p>



<h3 class="wp-block-heading">Bag Clip(s)</h3>



<p><a href="https://www.thingiverse.com/thing:330151">https://www.thingiverse.com/thing:330151</a></p>



<p><a href="https://www.prusaprinters.org/prints/27216-bag-clip-print-in-place-cam">https://www.prusaprinters.org/prints/27216-bag-clip-print-in-place-cam</a></p>



<p>The bag clips never stop being useful. These are the 2 designs that I have printed multiple times already:</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://vladfilippov.com/wp-content/uploads/2020/07/clip1.jpg" alt="" class="wp-image-1197" width="180" height="134"/></figure>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://vladfilippov.com/wp-content/uploads/2020/07/Untitled-2.jpg" alt="" class="wp-image-1198" width="192" height="197"/></figure>



<h3 class="wp-block-heading">Stratos Glider</h3>



<p><a href="https://www.thingiverse.com/thing:31944">https://www.thingiverse.com/thing:31944</a></p>



<p>This is one of the original gliders, all the way from 2012. I&#8217;ve had some luck make these fly and they do get stuck in trees sometimes.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1000" height="436" src="https://vladfilippov.com/wp-content/uploads/2020/07/glider1.jpg" alt="" class="wp-image-1199"/></figure>



<h3 class="wp-block-heading">Forbidden Tower</h3>



<p><a href="https://www.thingiverse.com/thing:2574499">https://www.thingiverse.com/thing:2574499</a></p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://vladfilippov.com/wp-content/uploads/2020/07/tower-601x1024.jpg" alt="" class="wp-image-1202" width="301" height="512"/></figure>



<p>Not a functional print, but looks beautiful and cheerful when painted.</p>



<h3 class="wp-block-heading">My own print designs</h3>



<p>The last one in this list is just a simple <strong>replacement piece</strong> for a portable desk. However it was my design and it serves me well now. Designing your own pieces, even simple ones, is very rewarding:</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://vladfilippov.com/wp-content/uploads/2020/07/coverx2.jpg" alt="" class="wp-image-1201" width="400" height="298"/><figcaption><br></figcaption></figure>



<p>If you have any suggestions or your favourite prints send them my way on <a rel="noreferrer noopener" href="https://twitter.com/vladikoff" target="_blank">Twitter</a>!</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1189</post-id>	</item>
	</channel>
</rss>
